(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("window")); else if(typeof define === 'function' && define.amd) define(["window"], factory); else if(typeof exports === 'object') exports["Mashlib"] = factory(require("window")); else root["Mashlib"] = factory(root["window"]); })(window, function(__WEBPACK_EXTERNAL_MODULE_xmldom__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/"; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ({ /***/ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js": /*!*****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/arrayLikeToArray.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } module.exports = _arrayLikeToArray; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/arrayWithHoles.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/arrayWithHoles.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } module.exports = _arrayWithHoles; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/assertThisInitialized.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/assertThisInitialized.js ***! \**********************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } module.exports = _assertThisInitialized; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/asyncToGenerator.js": /*!*****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/asyncToGenerator.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } module.exports = _asyncToGenerator; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/classCallCheck.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/classCallCheck.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } module.exports = _classCallCheck; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/construct.js": /*!**********************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/construct.js ***! \**********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var setPrototypeOf = __webpack_require__(/*! ./setPrototypeOf */ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js"); var isNativeReflectConstruct = __webpack_require__(/*! ./isNativeReflectConstruct */ "./node_modules/@babel/runtime/helpers/isNativeReflectConstruct.js"); function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { module.exports = _construct = Reflect.construct; } else { module.exports = _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } module.exports = _construct; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/createClass.js": /*!************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/createClass.js ***! \************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } module.exports = _createClass; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/defineProperty.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/defineProperty.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } module.exports = _defineProperty; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js": /*!*********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js ***! \*********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _arrayLikeToArray; }); function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _arrayWithoutHoles; }); /* harmony import */ var _babel_runtime_helpers_esm_arrayLikeToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js"); function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return Object(_babel_runtime_helpers_esm_arrayLikeToArray__WEBPACK_IMPORTED_MODULE_0__["default"])(arr); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js": /*!**************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _assertThisInitialized; }); function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/createClass.js": /*!****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/createClass.js ***! \****************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _createClass; }); function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/extends.js": /*!************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/extends.js ***! \************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _extends; }); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js": /*!******************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js ***! \******************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _inheritsLoose; }); /* harmony import */ var _babel_runtime_helpers_esm_setPrototypeOf__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/setPrototypeOf */ "./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js"); function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; Object(_babel_runtime_helpers_esm_setPrototypeOf__WEBPACK_IMPORTED_MODULE_0__["default"])(subClass, superClass); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/iterableToArray.js": /*!********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js ***! \********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _iterableToArray; }); function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _nonIterableSpread; }); function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js": /*!*********************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js ***! \*********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _objectWithoutPropertiesLoose; }); function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js": /*!*******************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js ***! \*******************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _setPrototypeOf; }); function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _toConsumableArray; }); /* harmony import */ var _babel_runtime_helpers_esm_arrayWithoutHoles__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/arrayWithoutHoles */ "./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js"); /* harmony import */ var _babel_runtime_helpers_esm_iterableToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/esm/iterableToArray */ "./node_modules/@babel/runtime/helpers/esm/iterableToArray.js"); /* harmony import */ var _babel_runtime_helpers_esm_unsupportedIterableToArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/esm/unsupportedIterableToArray */ "./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js"); /* harmony import */ var _babel_runtime_helpers_esm_nonIterableSpread__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/esm/nonIterableSpread */ "./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js"); function _toConsumableArray(arr) { return Object(_babel_runtime_helpers_esm_arrayWithoutHoles__WEBPACK_IMPORTED_MODULE_0__["default"])(arr) || Object(_babel_runtime_helpers_esm_iterableToArray__WEBPACK_IMPORTED_MODULE_1__["default"])(arr) || Object(_babel_runtime_helpers_esm_unsupportedIterableToArray__WEBPACK_IMPORTED_MODULE_2__["default"])(arr) || Object(_babel_runtime_helpers_esm_nonIterableSpread__WEBPACK_IMPORTED_MODULE_3__["default"])(); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js": /*!*******************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _unsupportedIterableToArray; }); /* harmony import */ var _babel_runtime_helpers_esm_arrayLikeToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js"); function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return Object(_babel_runtime_helpers_esm_arrayLikeToArray__WEBPACK_IMPORTED_MODULE_0__["default"])(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return Object(_babel_runtime_helpers_esm_arrayLikeToArray__WEBPACK_IMPORTED_MODULE_0__["default"])(o, minLen); } /***/ }), /***/ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/getPrototypeOf.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _getPrototypeOf(o) { module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } module.exports = _getPrototypeOf; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/inherits.js": /*!*********************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/inherits.js ***! \*********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var setPrototypeOf = __webpack_require__(/*! ./setPrototypeOf */ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js"); function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) setPrototypeOf(subClass, superClass); } module.exports = _inherits; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! \**********************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } module.exports = _interopRequireDefault; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/interopRequireWildcard.js": /*!***********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/interopRequireWildcard.js ***! \***********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var _typeof = __webpack_require__(/*! @babel/runtime/helpers/typeof */ "./node_modules/@babel/runtime/helpers/typeof.js"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } module.exports = _interopRequireWildcard; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/isNativeFunction.js": /*!*****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/isNativeFunction.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } module.exports = _isNativeFunction; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/isNativeReflectConstruct.js": /*!*************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/isNativeReflectConstruct.js ***! \*************************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } module.exports = _isNativeReflectConstruct; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js": /*!*********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js ***! \*********************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } module.exports = _iterableToArrayLimit; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/nonIterableRest.js": /*!****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/nonIterableRest.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } module.exports = _nonIterableRest; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js": /*!**************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js ***! \**************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var _typeof = __webpack_require__(/*! @babel/runtime/helpers/typeof */ "./node_modules/@babel/runtime/helpers/typeof.js"); var assertThisInitialized = __webpack_require__(/*! ./assertThisInitialized */ "./node_modules/@babel/runtime/helpers/assertThisInitialized.js"); function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return assertThisInitialized(self); } module.exports = _possibleConstructorReturn; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/setPrototypeOf.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _setPrototypeOf(o, p) { module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } module.exports = _setPrototypeOf; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/slicedToArray.js": /*!**************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/slicedToArray.js ***! \**************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var arrayWithHoles = __webpack_require__(/*! ./arrayWithHoles */ "./node_modules/@babel/runtime/helpers/arrayWithHoles.js"); var iterableToArrayLimit = __webpack_require__(/*! ./iterableToArrayLimit */ "./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js"); var unsupportedIterableToArray = __webpack_require__(/*! ./unsupportedIterableToArray */ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js"); var nonIterableRest = __webpack_require__(/*! ./nonIterableRest */ "./node_modules/@babel/runtime/helpers/nonIterableRest.js"); function _slicedToArray(arr, i) { return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); } module.exports = _slicedToArray; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/taggedTemplateLiteral.js": /*!**********************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/taggedTemplateLiteral.js ***! \**********************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } module.exports = _taggedTemplateLiteral; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/typeof.js": /*!*******************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/typeof.js ***! \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports) { function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { module.exports = _typeof = function _typeof(obj) { return typeof obj; }; } else { module.exports = _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } module.exports = _typeof; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js": /*!***************************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js ***! \***************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js"); function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); } module.exports = _unsupportedIterableToArray; /***/ }), /***/ "./node_modules/@babel/runtime/helpers/wrapNativeSuper.js": /*!****************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/wrapNativeSuper.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var getPrototypeOf = __webpack_require__(/*! ./getPrototypeOf */ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js"); var setPrototypeOf = __webpack_require__(/*! ./setPrototypeOf */ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js"); var isNativeFunction = __webpack_require__(/*! ./isNativeFunction */ "./node_modules/@babel/runtime/helpers/isNativeFunction.js"); var construct = __webpack_require__(/*! ./construct */ "./node_modules/@babel/runtime/helpers/construct.js"); function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return construct(Class, arguments, getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } module.exports = _wrapNativeSuper; /***/ }), /***/ "./node_modules/@babel/runtime/regenerator/index.js": /*!**********************************************************!*\ !*** ./node_modules/@babel/runtime/regenerator/index.js ***! \**********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(/*! regenerator-runtime */ "./node_modules/regenerator-runtime/runtime.js"); /***/ }), /***/ "./node_modules/@emotion/is-prop-valid/dist/is-prop-valid.browser.esm.js": /*!*******************************************************************************!*\ !*** ./node_modules/@emotion/is-prop-valid/dist/is-prop-valid.browser.esm.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _emotion_memoize__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @emotion/memoize */ "./node_modules/@emotion/memoize/dist/memoize.browser.esm.js"); var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|default|defer|dir|disabled|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|itemProp|itemScope|itemType|itemID|itemRef|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23 var index = Object(_emotion_memoize__WEBPACK_IMPORTED_MODULE_0__["default"])(function (prop) { return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 /* o */ && prop.charCodeAt(1) === 110 /* n */ && prop.charCodeAt(2) < 91; } /* Z+1 */ ); /* harmony default export */ __webpack_exports__["default"] = (index); /***/ }), /***/ "./node_modules/@emotion/memoize/dist/memoize.browser.esm.js": /*!*******************************************************************!*\ !*** ./node_modules/@emotion/memoize/dist/memoize.browser.esm.js ***! \*******************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); function memoize(fn) { var cache = {}; return function (arg) { if (cache[arg] === undefined) cache[arg] = fn(arg); return cache[arg]; }; } /* harmony default export */ __webpack_exports__["default"] = (memoize); /***/ }), /***/ "./node_modules/@solid/better-simple-slideshow/js/better-simple-slideshow.js": /*!***********************************************************************************!*\ !*** ./node_modules/@solid/better-simple-slideshow/js/better-simple-slideshow.js ***! \***********************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var makeBSS = function (el, options) { if (typeof document === 'undefined') { var document = options.dom; } var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshow $slideshow = {}, Slideshow = { init: function (el, options) { this.counter = 0; // to keep track of current slide this.el = el; // current slideshow container this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance this.numItems = this.$items.length; // total number of slides options = options || {}; // if options object not passed in, then set to empty object options.auto = options.auto || false; // if options.auto object not passed in, then set to false this.opts = { auto: (typeof options.auto === "undefined") ? false : options.auto, speed: (typeof options.auto.speed === "undefined") ? 1500 : options.auto.speed, pauseOnHover: (typeof options.auto.pauseOnHover === "undefined") ? false : options.auto.pauseOnHover, fullScreen: (typeof options.fullScreen === "undefined") ? false : options.fullScreen, swipe: (typeof options.swipe === "undefined") ? false : options.swipe }; this.$items[0].classList.add('bss-show'); // add show class to first figure this.injectControls(el); this.addEventListeners(el); if (this.opts.auto) { this.autoCycle(this.el, this.opts.speed, this.opts.pauseOnHover); } if (this.opts.fullScreen) { this.addFullScreen(this.el); } if (this.opts.swipe) { this.addSwipe(this.el); } }, showCurrent: function (i) { // increment or decrement this.counter depending on whether i === 1 or i === -1 if (i > 0) { this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1; } else { this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1; } // remove .show from whichever element currently has it // http://stackoverflow.com/a/16053538/2006057 [].forEach.call(this.$items, function (el) { el.classList.remove('bss-show'); }); // add .show to the one item that's supposed to have it this.$items[this.counter].classList.add('bss-show'); }, injectControls: function (el) { // build and inject prev/next controls // first create all the new elements var spanPrev = document.createElement("span"), spanNext = document.createElement("span"), docFrag = document.createDocumentFragment(); // add classes spanPrev.classList.add('bss-prev'); spanNext.classList.add('bss-next'); // add contents spanPrev.innerHTML = '«'; spanNext.innerHTML = '»'; // append elements to fragment, then append fragment to DOM docFrag.appendChild(spanPrev); docFrag.appendChild(spanNext); el.appendChild(docFrag); }, addEventListeners: function (el) { var that = this; el.querySelector('.bss-next').addEventListener('click', function () { that.showCurrent(1); // increment & show }, false); el.querySelector('.bss-prev').addEventListener('click', function () { that.showCurrent(-1); // decrement & show }, false); el.onkeydown = function (e) { e = e || window.event; if (e.keyCode === 37) { that.showCurrent(-1); // decrement & show } else if (e.keyCode === 39) { that.showCurrent(1); // increment & show } }; }, autoCycle: function (el, speed, pauseOnHover) { var that = this, interval = window.setInterval(function () { that.showCurrent(1); // increment & show }, speed); if (pauseOnHover) { el.addEventListener('mouseover', function () { interval = clearInterval(interval); }, false); el.addEventListener('mouseout', function () { interval = window.setInterval(function () { that.showCurrent(1); // increment & show }, speed); }, false); } // end pauseonhover }, addFullScreen: function(el){ var that = this, fsControl = document.createElement("span"); fsControl.classList.add('bss-fullscreen'); el.appendChild(fsControl); el.querySelector('.bss-fullscreen').addEventListener('click', function () { that.toggleFullScreen(el); }, false); }, addSwipe: function(el){ var that = this, ht = new Hammer(el); ht.on('swiperight', function(e) { that.showCurrent(-1); // decrement & show }); ht.on('swipeleft', function(e) { that.showCurrent(1); // increment & show }); }, toggleFullScreen: function(el){ // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode if (!document.fullscreenElement && // alternative standard method !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods if (document.documentElement.requestFullscreen) { el.requestFullscreen(); } else if (document.documentElement.msRequestFullscreen) { el.msRequestFullscreen(); } else if (document.documentElement.mozRequestFullScreen) { el.mozRequestFullScreen(); } else if (document.documentElement.webkitRequestFullscreen) { el.webkitRequestFullscreen(el.ALLOW_KEYBOARD_INPUT); } } else { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } } } // end toggleFullScreen }; // end Slideshow object ..... // make instances of Slideshow as needed [].forEach.call($slideshows, function (el) { $slideshow = Object.create(Slideshow); $slideshow.init(el, options); }); }; if ( true && module.exports) { module.exports = makeBSS } /***/ }), /***/ "./node_modules/activitystreams-pane/lib/Pane.js": /*!*******************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/Pane.js ***! \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Pane = void 0; var React = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var note_1 = __webpack_require__(/*! ./note */ "./node_modules/activitystreams-pane/lib/note/index.js"); exports.Pane = function (_a) { var subject = _a.subject, context = _a.context; var store = context.session.store; var note = note_1.useNote(subject, store); return React.createElement(note_1.NoteCard, __assign({}, note)); }; //# sourceMappingURL=Pane.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/dom.js": /*!******************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/dom.js ***! \******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createElement = void 0; var react_dom_1 = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"); function createElement(jsx) { var element = document.createElement("div"); element.style.padding = "1em"; react_dom_1.render(jsx, element); return element; } exports.createElement = createElement; //# sourceMappingURL=dom.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/index.js": /*!********************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/index.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var React = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var solid_ui_1 = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var dom_1 = __webpack_require__(/*! ./dom */ "./node_modules/activitystreams-pane/lib/dom.js"); var Pane_1 = __webpack_require__(/*! ./Pane */ "./node_modules/activitystreams-pane/lib/Pane.js"); var thisPane = { global: false, icon: solid_ui_1.icons.iconBase + "noun_15695.svg", name: "activitystreams", label: function (subject, context) { var t = context.session.store.findTypeURIs(subject); if (t[solid_ui_1.ns.as("Note").uri]) { return "Note"; } return null; }, render: function (subject, context) { return dom_1.createElement(React.createElement(Pane_1.Pane, { subject: subject, context: context })); }, }; exports.default = thisPane; //# sourceMappingURL=index.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/AttributionTag.js": /*!**********************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/AttributionTag.js ***! \**********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AttributionTag = void 0; var React = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var types_1 = __webpack_require__(/*! ./types */ "./node_modules/activitystreams-pane/lib/note/types.js"); exports.AttributionTag = function (_a) { var to = _a.to; if (types_1.isLinkAttribution(to)) { return React.createElement("a", { href: to.uri }, to.uri); } else if (types_1.isPersonAttribution(to)) { return React.createElement(PersonAttributionTag, __assign({}, to)); } else { return null; } }; var PersonAttributionTag = function (_a) { var webId = _a.webId, name = _a.name, imageSrc = _a.imageSrc; return (React.createElement(React.Fragment, null, imageSrc && React.createElement("img", { height: "47", width: "47", alt: name, src: imageSrc }), React.createElement("a", { href: webId }, name))); }; //# sourceMappingURL=AttributionTag.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/FormattedDate.js": /*!*********************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/FormattedDate.js ***! \*********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormattedDate = void 0; var React = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var timeago_js_1 = __webpack_require__(/*! timeago.js */ "./node_modules/timeago.js/esm/index.js"); var twoDigitsDateTime = { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", }; exports.FormattedDate = function (_a) { var value = _a.value, className = _a.className; if (!value) return null; var formatted = value.toLocaleDateString(undefined, twoDigitsDateTime); var relative = timeago_js_1.format(value); return (React.createElement("p", { className: className }, relative, " \u00B7 ", formatted)); }; //# sourceMappingURL=FormattedDate.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/NoteCard.js": /*!****************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/NoteCard.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NoteCard = void 0; var React = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var react_jss_1 = __webpack_require__(/*! react-jss */ "./node_modules/react-jss/dist/react-jss.esm.js"); var FormattedDate_1 = __webpack_require__(/*! ./FormattedDate */ "./node_modules/activitystreams-pane/lib/note/FormattedDate.js"); var AttributionTag_1 = __webpack_require__(/*! ./AttributionTag */ "./node_modules/activitystreams-pane/lib/note/AttributionTag.js"); var useStyles = react_jss_1.createUseStyles({ card: { fontFamily: "sans-serif", display: "flex", flexWrap: "wrap", borderRadius: "4px", flexDirection: "column", justifyContent: "center", padding: "1em", boxShadow: "0 1px 5px rgba(0,0,0,0.2)", transition: "all .25s ease-in-out", maxWidth: 632, }, content: { fontSize: "larger", }, date: { color: "rgb(0, 0, 0, 60%)", }, attribution: { display: "flex", alignItems: "center", fontWeight: "bold", "& a": { color: "black", textDecoration: "none", }, "& a:hover": { textDecoration: "underline", }, "& img": { marginRight: 5, width: 47, borderRadius: 5, }, }, }); exports.NoteCard = function (_a) { var content = _a.content, published = _a.published, attributedTo = _a.attributedTo; var classes = useStyles(); return (React.createElement("div", { className: classes.card }, React.createElement("div", { className: classes.attribution }, React.createElement(AttributionTag_1.AttributionTag, { to: attributedTo })), React.createElement("p", { className: classes.content }, content), React.createElement(FormattedDate_1.FormattedDate, { className: classes.date, value: published }))); }; //# sourceMappingURL=NoteCard.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/index.js": /*!*************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/index.js ***! \*************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useNote = exports.NoteCard = void 0; var NoteCard_1 = __webpack_require__(/*! ./NoteCard */ "./node_modules/activitystreams-pane/lib/note/NoteCard.js"); Object.defineProperty(exports, "NoteCard", { enumerable: true, get: function () { return NoteCard_1.NoteCard; } }); var useNote_1 = __webpack_require__(/*! ./useNote */ "./node_modules/activitystreams-pane/lib/note/useNote.js"); Object.defineProperty(exports, "useNote", { enumerable: true, get: function () { return useNote_1.useNote; } }); //# sourceMappingURL=index.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/store/attribution.js": /*!*************************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/store/attribution.js ***! \*************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchAttribution = exports.readAttribution = void 0; var solid_ui_1 = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var rdflib_1 = __webpack_require__(/*! rdflib */ "./node_modules/rdflib/esm/index.js"); /** * Constructs an attribution object for the node the subject is attributed to. */ function readAttribution(subject, store) { var attributedTo = store.any(subject, solid_ui_1.ns.as("attributedTo")); return read(attributedTo, store); } exports.readAttribution = readAttribution; function containsPersonType(types) { var as = solid_ui_1.ns.as("Person").uri; var foaf = solid_ui_1.ns.foaf("Person").uri; var vcard = solid_ui_1.ns.vcard("Individual").uri; var schema = solid_ui_1.ns.schema("Person").uri; return types[as] || types[foaf] || types[vcard] || types[schema]; } /** * Constructs an attribution object for the given node with data read from the store */ function read(attributedTo, store) { if (attributedTo instanceof rdflib_1.NamedNode) { var types = store.findTypeURIs(attributedTo); if (containsPersonType(types)) { return readPerson(store, attributedTo); } else { return { discriminator: "LinkAttribution", uri: attributedTo.uri, }; } } return { discriminator: "NoAttribution", }; } function readPerson(store, attributedTo) { var name = store.anyValue(attributedTo, solid_ui_1.ns.as("name")) || store.anyValue(attributedTo, solid_ui_1.ns.foaf("name")) || store.anyValue(attributedTo, solid_ui_1.ns.vcard("fn")) || store.anyValue(attributedTo, solid_ui_1.ns.schema("name")) || ""; var imageSrc = readImageSrc(store, attributedTo); return { discriminator: "PersonAttribution", webId: attributedTo.uri, name: name, imageSrc: imageSrc, }; } function readImageSrc(store, attributedTo) { var image = store.anyValue(attributedTo, solid_ui_1.ns.as("image")); if (image) { return store.anyValue(rdflib_1.sym(image), solid_ui_1.ns.as("url")) || undefined; } return (store.anyValue(attributedTo, solid_ui_1.ns.foaf("img")) || store.anyValue(attributedTo, solid_ui_1.ns.vcard("hasPhoto")) || undefined); } /** * Fetches the given attribution uri and returns an updated attribution with data from the fetched resource */ function fetchAttribution(attribution, store) { return __awaiter(this, void 0, void 0, function () { var attributionNode; return __generator(this, function (_a) { switch (_a.label) { case 0: attributionNode = rdflib_1.sym(attribution.uri); return [4 /*yield*/, store.fetcher.load(attributionNode)]; case 1: _a.sent(); return [2 /*return*/, read(attributionNode, store)]; } }); }); } exports.fetchAttribution = fetchAttribution; //# sourceMappingURL=attribution.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/store/note.js": /*!******************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/store/note.js ***! \******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.read = void 0; var solid_ui_1 = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var attribution_1 = __webpack_require__(/*! ./attribution */ "./node_modules/activitystreams-pane/lib/note/store/attribution.js"); function read(subject, store) { var content = store.any(subject, solid_ui_1.ns.as("content")); var published = store.any(subject, solid_ui_1.ns.as("published")); var attributedTo = attribution_1.readAttribution(subject, store); if (!content) { return null; } return { content: content.value, published: published && new Date(published.value), attributedTo: attributedTo, }; } exports.read = read; //# sourceMappingURL=note.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/types.js": /*!*************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/types.js ***! \*************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isPersonAttribution = exports.isLinkAttribution = void 0; function isLinkAttribution(attribution) { return attribution.discriminator === "LinkAttribution"; } exports.isLinkAttribution = isLinkAttribution; function isPersonAttribution(attribution) { return attribution.discriminator === "PersonAttribution"; } exports.isPersonAttribution = isPersonAttribution; //# sourceMappingURL=types.js.map /***/ }), /***/ "./node_modules/activitystreams-pane/lib/note/useNote.js": /*!***************************************************************!*\ !*** ./node_modules/activitystreams-pane/lib/note/useNote.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useNote = void 0; var note_1 = __webpack_require__(/*! ./store/note */ "./node_modules/activitystreams-pane/lib/note/store/note.js"); var types_1 = __webpack_require__(/*! ./types */ "./node_modules/activitystreams-pane/lib/note/types.js"); var react_1 = __webpack_require__(/*! react */ "./node_modules/react/index.js"); var attribution_1 = __webpack_require__(/*! ./store/attribution */ "./node_modules/activitystreams-pane/lib/note/store/attribution.js"); exports.useNote = function (subject, store) { var _a = react_1.useState(note_1.read(subject, store)), note = _a[0], setNote = _a[1]; react_1.useEffect(function () { function fetch() { return __awaiter(this, void 0, void 0, function () { var attribution; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!types_1.isLinkAttribution(note.attributedTo)) return [3 /*break*/, 2]; return [4 /*yield*/, attribution_1.fetchAttribution(note.attributedTo, store)]; case 1: attribution = _a.sent(); setNote(__assign(__assign({}, note), { attributedTo: attribution })); _a.label = 2; case 2: return [2 /*return*/]; } }); }); } fetch(); }, []); return note; }; //# sourceMappingURL=useNote.js.map /***/ }), /***/ "./node_modules/async/dist/async.mjs": /*!*******************************************!*\ !*** ./node_modules/async/dist/async.mjs ***! \*******************************************/ /*! exports provided: default, apply, applyEach, applyEachSeries, asyncify, auto, autoInject, cargo, cargoQueue, compose, concat, concatLimit, concatSeries, constant, detect, detectLimit, detectSeries, dir, doUntil, doWhilst, each, eachLimit, eachOf, eachOfLimit, eachOfSeries, eachSeries, ensureAsync, every, everyLimit, everySeries, filter, filterLimit, filterSeries, forever, groupBy, groupByLimit, groupBySeries, log, map, mapLimit, mapSeries, mapValues, mapValuesLimit, mapValuesSeries, memoize, nextTick, parallel, parallelLimit, priorityQueue, queue, race, reduce, reduceRight, reflect, reflectAll, reject, rejectLimit, rejectSeries, retry, retryable, seq, series, setImmediate, some, someLimit, someSeries, sortBy, timeout, times, timesLimit, timesSeries, transform, tryEach, unmemoize, until, waterfall, whilst, all, allLimit, allSeries, any, anyLimit, anySeries, find, findLimit, findSeries, flatMap, flatMapLimit, flatMapSeries, forEach, forEachSeries, forEachLimit, forEachOf, forEachOfSeries, forEachOfLimit, inject, foldl, foldr, select, selectLimit, selectSeries, wrapSync, during, doDuring */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "apply", function() { return apply; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyEach", function() { return applyEach$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyEachSeries", function() { return applyEachSeries; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asyncify", function() { return asyncify; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auto", function() { return auto; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autoInject", function() { return autoInject; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cargo", function() { return cargo; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cargoQueue", function() { return cargo$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compose", function() { return compose; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatLimit", function() { return concatLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatSeries", function() { return concatSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "constant", function() { return constant; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "detect", function() { return detect$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "detectLimit", function() { return detectLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "detectSeries", function() { return detectSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dir", function() { return dir; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "doUntil", function() { return doUntil; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "doWhilst", function() { return doWhilst$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "each", function() { return each; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eachLimit", function() { return eachLimit$2; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eachOf", function() { return eachOf$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eachOfLimit", function() { return eachOfLimit$2; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eachOfSeries", function() { return eachOfSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eachSeries", function() { return eachSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ensureAsync", function() { return ensureAsync; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "every", function() { return every$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "everyLimit", function() { return everyLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "everySeries", function() { return everySeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return filter$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filterLimit", function() { return filterLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filterSeries", function() { return filterSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forever", function() { return forever$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return groupBy; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupByLimit", function() { return groupByLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupBySeries", function() { return groupBySeries; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return log; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "map", function() { return map$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapLimit", function() { return mapLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapSeries", function() { return mapSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapValues", function() { return mapValues; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapValuesLimit", function() { return mapValuesLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapValuesSeries", function() { return mapValuesSeries; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "memoize", function() { return memoize; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "nextTick", function() { return nextTick; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallel", function() { return parallel; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelLimit", function() { return parallelLimit; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "priorityQueue", function() { return priorityQueue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queue", function() { return queue$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduceRight", function() { return reduceRight; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reflect", function() { return reflect; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reflectAll", function() { return reflectAll; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reject", function() { return reject$2; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rejectLimit", function() { return rejectLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rejectSeries", function() { return rejectSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return retry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retryable", function() { return retryable; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "seq", function() { return seq; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "series", function() { return series; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setImmediate", function() { return setImmediate$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "some", function() { return some$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "someLimit", function() { return someLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "someSeries", function() { return someSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sortBy", function() { return sortBy$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "times", function() { return times; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timesLimit", function() { return timesLimit; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timesSeries", function() { return timesSeries; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transform", function() { return transform; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tryEach", function() { return tryEach$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unmemoize", function() { return unmemoize; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "until", function() { return until; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waterfall", function() { return waterfall$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "whilst", function() { return whilst$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "all", function() { return every$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allLimit", function() { return everyLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allSeries", function() { return everySeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "any", function() { return some$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "anyLimit", function() { return someLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "anySeries", function() { return someSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "find", function() { return detect$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findLimit", function() { return detectLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findSeries", function() { return detectSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return concat$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "flatMapLimit", function() { return concatLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "flatMapSeries", function() { return concatSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEach", function() { return each; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEachSeries", function() { return eachSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEachLimit", function() { return eachLimit$2; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEachOf", function() { return eachOf$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEachOfSeries", function() { return eachOfSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEachOfLimit", function() { return eachOfLimit$2; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inject", function() { return reduce$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "foldl", function() { return reduce$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "foldr", function() { return reduceRight; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "select", function() { return filter$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "selectLimit", function() { return filterLimit$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "selectSeries", function() { return filterSeries$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wrapSync", function() { return asyncify; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "during", function() { return whilst$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "doDuring", function() { return doWhilst$1; }); /** * Creates a continuation function with some arguments already applied. * * Useful as a shorthand when combined with other control flow functions. Any * arguments passed to the returned function are added to the arguments * originally passed to apply. * * @name apply * @static * @memberOf module:Utils * @method * @category Util * @param {Function} fn - The function you want to eventually apply all * arguments to. Invokes with (arguments...). * @param {...*} arguments... - Any number of arguments to automatically apply * when the continuation is called. * @returns {Function} the partially-applied function * @example * * // using apply * async.parallel([ * async.apply(fs.writeFile, 'testfile1', 'test1'), * async.apply(fs.writeFile, 'testfile2', 'test2') * ]); * * * // the same process without using apply * async.parallel([ * function(callback) { * fs.writeFile('testfile1', 'test1', callback); * }, * function(callback) { * fs.writeFile('testfile2', 'test2', callback); * } * ]); * * // It's possible to pass any number of additional arguments when calling the * // continuation: * * node> var fn = async.apply(sys.puts, 'one'); * node> fn('two', 'three'); * one * two * three */ function apply(fn, ...args) { return (...callArgs) => fn(...args,...callArgs); } function initialParams (fn) { return function (...args/*, callback*/) { var callback = args.pop(); return fn.call(this, args, callback); }; } /* istanbul ignore file */ var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; function fallback(fn) { setTimeout(fn, 0); } function wrap(defer) { return (fn, ...args) => defer(() => fn(...args)); } var _defer; if (hasSetImmediate) { _defer = setImmediate; } else if (hasNextTick) { _defer = process.nextTick; } else { _defer = fallback; } var setImmediate$1 = wrap(_defer); /** * Take a sync function and make it async, passing its return value to a * callback. This is useful for plugging sync functions into a waterfall, * series, or other async functions. Any arguments passed to the generated * function will be passed to the wrapped function (except for the final * callback argument). Errors thrown will be passed to the callback. * * If the function passed to `asyncify` returns a Promise, that promises's * resolved/rejected state will be used to call the callback, rather than simply * the synchronous return value. * * This also means you can asyncify ES2017 `async` functions. * * @name asyncify * @static * @memberOf module:Utils * @method * @alias wrapSync * @category Util * @param {Function} func - The synchronous function, or Promise-returning * function to convert to an {@link AsyncFunction}. * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be * invoked with `(args..., callback)`. * @example * * // passing a regular synchronous function * async.waterfall([ * async.apply(fs.readFile, filename, "utf8"), * async.asyncify(JSON.parse), * function (data, next) { * // data is the result of parsing the text. * // If there was a parsing error, it would have been caught. * } * ], callback); * * // passing a function returning a promise * async.waterfall([ * async.apply(fs.readFile, filename, "utf8"), * async.asyncify(function (contents) { * return db.model.create(contents); * }), * function (model, next) { * // `model` is the instantiated model object. * // If there was an error, this function would be skipped. * } * ], callback); * * // es2017 example, though `asyncify` is not needed if your JS environment * // supports async functions out of the box * var q = async.queue(async.asyncify(async function(file) { * var intermediateStep = await processFile(file); * return await somePromise(intermediateStep) * })); * * q.push(files); */ function asyncify(func) { if (isAsync(func)) { return function (...args/*, callback*/) { const callback = args.pop(); const promise = func.apply(this, args); return handlePromise(promise, callback) } } return initialParams(function (args, callback) { var result; try { result = func.apply(this, args); } catch (e) { return callback(e); } // if result is Promise object if (result && typeof result.then === 'function') { return handlePromise(result, callback) } else { callback(null, result); } }); } function handlePromise(promise, callback) { return promise.then(value => { invokeCallback(callback, null, value); }, err => { invokeCallback(callback, err && err.message ? err : new Error(err)); }); } function invokeCallback(callback, error, value) { try { callback(error, value); } catch (err) { setImmediate$1(e => { throw e }, err); } } function isAsync(fn) { return fn[Symbol.toStringTag] === 'AsyncFunction'; } function isAsyncGenerator(fn) { return fn[Symbol.toStringTag] === 'AsyncGenerator'; } function isAsyncIterable(obj) { return typeof obj[Symbol.asyncIterator] === 'function'; } function wrapAsync(asyncFn) { if (typeof asyncFn !== 'function') throw new Error('expected a function') return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn; } // conditionally promisify a function. // only return a promise if a callback is omitted function awaitify (asyncFn, arity = asyncFn.length) { if (!arity) throw new Error('arity is undefined') function awaitable (...args) { if (typeof args[arity - 1] === 'function') { return asyncFn.apply(this, args) } return new Promise((resolve, reject) => { args[arity - 1] = (err, ...cbArgs) => { if (err) return reject(err) resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]); }; asyncFn.apply(this, args); }) } return awaitable } function applyEach (eachfn) { return function applyEach(fns, ...callArgs) { const go = awaitify(function (callback) { var that = this; return eachfn(fns, (fn, cb) => { wrapAsync(fn).apply(that, callArgs.concat(cb)); }, callback); }); return go; }; } function _asyncMap(eachfn, arr, iteratee, callback) { arr = arr || []; var results = []; var counter = 0; var _iteratee = wrapAsync(iteratee); return eachfn(arr, (value, _, iterCb) => { var index = counter++; _iteratee(value, (err, v) => { results[index] = v; iterCb(err); }); }, err => { callback(err, results); }); } function isArrayLike(value) { return value && typeof value.length === 'number' && value.length >= 0 && value.length % 1 === 0; } // A temporary value used to identify if the loop should be broken. // See #1064, #1293 const breakLoop = {}; function once(fn) { function wrapper (...args) { if (fn === null) return; var callFn = fn; fn = null; callFn.apply(this, args); } Object.assign(wrapper, fn); return wrapper } function getIterator (coll) { return coll[Symbol.iterator] && coll[Symbol.iterator](); } function createArrayIterator(coll) { var i = -1; var len = coll.length; return function next() { return ++i < len ? {value: coll[i], key: i} : null; } } function createES2015Iterator(iterator) { var i = -1; return function next() { var item = iterator.next(); if (item.done) return null; i++; return {value: item.value, key: i}; } } function createObjectIterator(obj) { var okeys = obj ? Object.keys(obj) : []; var i = -1; var len = okeys.length; return function next() { var key = okeys[++i]; return i < len ? {value: obj[key], key} : null; }; } function createIterator(coll) { if (isArrayLike(coll)) { return createArrayIterator(coll); } var iterator = getIterator(coll); return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); } function onlyOnce(fn) { return function (...args) { if (fn === null) throw new Error("Callback was already called."); var callFn = fn; fn = null; callFn.apply(this, args); }; } // for async generators function asyncEachOfLimit(generator, limit, iteratee, callback) { let done = false; let canceled = false; let awaiting = false; let running = 0; let idx = 0; function replenish() { //console.log('replenish') if (running >= limit || awaiting || done) return //console.log('replenish awaiting') awaiting = true; generator.next().then(({value, done: iterDone}) => { //console.log('got value', value) if (canceled || done) return awaiting = false; if (iterDone) { done = true; if (running <= 0) { //console.log('done nextCb') callback(null); } return; } running++; iteratee(value, idx, iterateeCallback); idx++; replenish(); }).catch(handleError); } function iterateeCallback(err, result) { //console.log('iterateeCallback') running -= 1; if (canceled) return if (err) return handleError(err) if (err === false) { done = true; canceled = true; return } if (result === breakLoop || (done && running <= 0)) { done = true; //console.log('done iterCb') return callback(null); } replenish(); } function handleError(err) { if (canceled) return awaiting = false; done = true; callback(err); } replenish(); } var eachOfLimit = (limit) => { return (obj, iteratee, callback) => { callback = once(callback); if (limit <= 0) { throw new RangeError('concurrency limit cannot be less than 1') } if (!obj) { return callback(null); } if (isAsyncGenerator(obj)) { return asyncEachOfLimit(obj, limit, iteratee, callback) } if (isAsyncIterable(obj)) { return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback) } var nextElem = createIterator(obj); var done = false; var canceled = false; var running = 0; var looping = false; function iterateeCallback(err, value) { if (canceled) return running -= 1; if (err) { done = true; callback(err); } else if (err === false) { done = true; canceled = true; } else if (value === breakLoop || (done && running <= 0)) { done = true; return callback(null); } else if (!looping) { replenish(); } } function replenish () { looping = true; while (running < limit && !done) { var elem = nextElem(); if (elem === null) { done = true; if (running <= 0) { callback(null); } return; } running += 1; iteratee(elem.value, elem.key, onlyOnce(iterateeCallback)); } looping = false; } replenish(); }; }; /** * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a * time. * * @name eachOfLimit * @static * @memberOf module:Collections * @method * @see [async.eachOf]{@link module:Collections.eachOf} * @alias forEachOfLimit * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async function to apply to each * item in `coll`. The `key` is the item's key, or index in the case of an * array. * Invoked with (item, key, callback). * @param {Function} [callback] - A callback which is called when all * `iteratee` functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted */ function eachOfLimit$1(coll, limit, iteratee, callback) { return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback); } var eachOfLimit$2 = awaitify(eachOfLimit$1, 4); // eachOf implementation optimized for array-likes function eachOfArrayLike(coll, iteratee, callback) { callback = once(callback); var index = 0, completed = 0, {length} = coll, canceled = false; if (length === 0) { callback(null); } function iteratorCallback(err, value) { if (err === false) { canceled = true; } if (canceled === true) return if (err) { callback(err); } else if ((++completed === length) || value === breakLoop) { callback(null); } } for (; index < length; index++) { iteratee(coll[index], index, onlyOnce(iteratorCallback)); } } // a generic version of eachOf which can handle array, object, and iterator cases. function eachOfGeneric (coll, iteratee, callback) { return eachOfLimit$2(coll, Infinity, iteratee, callback); } /** * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument * to the iteratee. * * @name eachOf * @static * @memberOf module:Collections * @method * @alias forEachOf * @category Collection * @see [async.each]{@link module:Collections.each} * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - A function to apply to each * item in `coll`. * The `key` is the item's key, or index in the case of an array. * Invoked with (item, key, callback). * @param {Function} [callback] - A callback which is called when all * `iteratee` functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted * @example * * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; * var configs = {}; * * async.forEachOf(obj, function (value, key, callback) { * fs.readFile(__dirname + value, "utf8", function (err, data) { * if (err) return callback(err); * try { * configs[key] = JSON.parse(data); * } catch (e) { * return callback(e); * } * callback(); * }); * }, function (err) { * if (err) console.error(err.message); * // configs is now a map of JSON data * doSomethingWith(configs); * }); */ function eachOf(coll, iteratee, callback) { var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric; return eachOfImplementation(coll, wrapAsync(iteratee), callback); } var eachOf$1 = awaitify(eachOf, 3); /** * Produces a new collection of values by mapping each value in `coll` through * the `iteratee` function. The `iteratee` is called with an item from `coll` * and a callback for when it has finished processing. Each of these callback * takes 2 arguments: an `error`, and the transformed item from `coll`. If * `iteratee` passes an error to its callback, the main `callback` (for the * `map` function) is immediately called with the error. * * Note, that since this function applies the `iteratee` to each item in * parallel, there is no guarantee that the `iteratee` functions will complete * in order. However, the results array will be in the same order as the * original `coll`. * * If `map` is passed an Object, the results will be an Array. The results * will roughly be in the order of the original Objects' keys (but this can * vary across JavaScript engines). * * @name map * @static * @memberOf module:Collections * @method * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with the transformed item. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Results is an Array of the * transformed items from the `coll`. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed * @example * * async.map(['file1','file2','file3'], fs.stat, function(err, results) { * // results is now an array of stats for each file * }); */ function map (coll, iteratee, callback) { return _asyncMap(eachOf$1, coll, iteratee, callback) } var map$1 = awaitify(map, 3); /** * Applies the provided arguments to each function in the array, calling * `callback` after all functions have completed. If you only provide the first * argument, `fns`, then it will return a function which lets you pass in the * arguments as if it were a single function call. If more arguments are * provided, `callback` is required while `args` is still optional. The results * for each of the applied async functions are passed to the final callback * as an array. * * @name applyEach * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s * to all call with the same arguments * @param {...*} [args] - any number of separate arguments to pass to the * function. * @param {Function} [callback] - the final argument should be the callback, * called when all functions have completed processing. * @returns {AsyncFunction} - Returns a function that takes no args other than * an optional callback, that is the result of applying the `args` to each * of the functions. * @example * * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket') * * appliedFn((err, results) => { * // results[0] is the results for `enableSearch` * // results[1] is the results for `updateSchema` * }); * * // partial application example: * async.each( * buckets, * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(), * callback * ); */ var applyEach$1 = applyEach(map$1); /** * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. * * @name eachOfSeries * @static * @memberOf module:Collections * @method * @see [async.eachOf]{@link module:Collections.eachOf} * @alias forEachOfSeries * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * Invoked with (item, key, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted */ function eachOfSeries(coll, iteratee, callback) { return eachOfLimit$2(coll, 1, iteratee, callback) } var eachOfSeries$1 = awaitify(eachOfSeries, 3); /** * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. * * @name mapSeries * @static * @memberOf module:Collections * @method * @see [async.map]{@link module:Collections.map} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with the transformed item. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Results is an array of the * transformed items from the `coll`. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed */ function mapSeries (coll, iteratee, callback) { return _asyncMap(eachOfSeries$1, coll, iteratee, callback) } var mapSeries$1 = awaitify(mapSeries, 3); /** * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. * * @name applyEachSeries * @static * @memberOf module:ControlFlow * @method * @see [async.applyEach]{@link module:ControlFlow.applyEach} * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all * call with the same arguments * @param {...*} [args] - any number of separate arguments to pass to the * function. * @param {Function} [callback] - the final argument should be the callback, * called when all functions have completed processing. * @returns {AsyncFunction} - A function, that when called, is the result of * appling the `args` to the list of functions. It takes no args, other than * a callback. */ var applyEachSeries = applyEach(mapSeries$1); const PROMISE_SYMBOL = Symbol('promiseCallback'); function promiseCallback () { let resolve, reject; function callback (err, ...args) { if (err) return reject(err) resolve(args.length > 1 ? args : args[0]); } callback[PROMISE_SYMBOL] = new Promise((res, rej) => { resolve = res, reject = rej; }); return callback } /** * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on * their requirements. Each function can optionally depend on other functions * being completed first, and each function is run as soon as its requirements * are satisfied. * * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence * will stop. Further tasks will not execute (so any other functions depending * on it will not run), and the main `callback` is immediately called with the * error. * * {@link AsyncFunction}s also receive an object containing the results of functions which * have completed so far as the first argument, if they have dependencies. If a * task function has no dependencies, it will only be passed a callback. * * @name auto * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Object} tasks - An object. Each of its properties is either a * function or an array of requirements, with the {@link AsyncFunction} itself the last item * in the array. The object's key of a property serves as the name of the task * defined by that property, i.e. can be used when specifying requirements for * other tasks. The function receives one or two arguments: * * a `results` object, containing the results of the previously executed * functions, only passed if the task has any dependencies, * * a `callback(err, result)` function, which must be called when finished, * passing an `error` (which can be `null`) and the result of the function's * execution. * @param {number} [concurrency=Infinity] - An optional `integer` for * determining the maximum number of tasks that can be run in parallel. By * default, as many as possible. * @param {Function} [callback] - An optional callback which is called when all * the tasks have been completed. It receives the `err` argument if any `tasks` * pass an error to their callback. Results are always returned; however, if an * error occurs, no further `tasks` will be performed, and the results object * will only contain partial results. Invoked with (err, results). * @returns {Promise} a promise, if a callback is not passed * @example * * async.auto({ * // this function will just be passed a callback * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'), * showData: ['readData', function(results, cb) { * // results.readData is the file's contents * // ... * }] * }, callback); * * async.auto({ * get_data: function(callback) { * console.log('in get_data'); * // async code to get some data * callback(null, 'data', 'converted to array'); * }, * make_folder: function(callback) { * console.log('in make_folder'); * // async code to create a directory to store a file in * // this is run at the same time as getting the data * callback(null, 'folder'); * }, * write_file: ['get_data', 'make_folder', function(results, callback) { * console.log('in write_file', JSON.stringify(results)); * // once there is some data and the directory exists, * // write the data to a file in the directory * callback(null, 'filename'); * }], * email_link: ['write_file', function(results, callback) { * console.log('in email_link', JSON.stringify(results)); * // once the file is written let's email a link to it... * // results.write_file contains the filename returned by write_file. * callback(null, {'file':results.write_file, 'email':'user@example.com'}); * }] * }, function(err, results) { * console.log('err = ', err); * console.log('results = ', results); * }); */ function auto(tasks, concurrency, callback) { if (typeof concurrency !== 'number') { // concurrency is optional, shift the args. callback = concurrency; concurrency = null; } callback = once(callback || promiseCallback()); var numTasks = Object.keys(tasks).length; if (!numTasks) { return callback(null); } if (!concurrency) { concurrency = numTasks; } var results = {}; var runningTasks = 0; var canceled = false; var hasError = false; var listeners = Object.create(null); var readyTasks = []; // for cycle detection: var readyToCheck = []; // tasks that have been identified as reachable // without the possibility of returning to an ancestor task var uncheckedDependencies = {}; Object.keys(tasks).forEach(key => { var task = tasks[key]; if (!Array.isArray(task)) { // no dependencies enqueueTask(key, [task]); readyToCheck.push(key); return; } var dependencies = task.slice(0, task.length - 1); var remainingDependencies = dependencies.length; if (remainingDependencies === 0) { enqueueTask(key, task); readyToCheck.push(key); return; } uncheckedDependencies[key] = remainingDependencies; dependencies.forEach(dependencyName => { if (!tasks[dependencyName]) { throw new Error('async.auto task `' + key + '` has a non-existent dependency `' + dependencyName + '` in ' + dependencies.join(', ')); } addListener(dependencyName, () => { remainingDependencies--; if (remainingDependencies === 0) { enqueueTask(key, task); } }); }); }); checkForDeadlocks(); processQueue(); function enqueueTask(key, task) { readyTasks.push(() => runTask(key, task)); } function processQueue() { if (canceled) return if (readyTasks.length === 0 && runningTasks === 0) { return callback(null, results); } while(readyTasks.length && runningTasks < concurrency) { var run = readyTasks.shift(); run(); } } function addListener(taskName, fn) { var taskListeners = listeners[taskName]; if (!taskListeners) { taskListeners = listeners[taskName] = []; } taskListeners.push(fn); } function taskComplete(taskName) { var taskListeners = listeners[taskName] || []; taskListeners.forEach(fn => fn()); processQueue(); } function runTask(key, task) { if (hasError) return; var taskCallback = onlyOnce((err, ...result) => { runningTasks--; if (err === false) { canceled = true; return } if (result.length < 2) { [result] = result; } if (err) { var safeResults = {}; Object.keys(results).forEach(rkey => { safeResults[rkey] = results[rkey]; }); safeResults[key] = result; hasError = true; listeners = Object.create(null); if (canceled) return callback(err, safeResults); } else { results[key] = result; taskComplete(key); } }); runningTasks++; var taskFn = wrapAsync(task[task.length - 1]); if (task.length > 1) { taskFn(results, taskCallback); } else { taskFn(taskCallback); } } function checkForDeadlocks() { // Kahn's algorithm // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html var currentTask; var counter = 0; while (readyToCheck.length) { currentTask = readyToCheck.pop(); counter++; getDependents(currentTask).forEach(dependent => { if (--uncheckedDependencies[dependent] === 0) { readyToCheck.push(dependent); } }); } if (counter !== numTasks) { throw new Error( 'async.auto cannot execute tasks due to a recursive dependency' ); } } function getDependents(taskName) { var result = []; Object.keys(tasks).forEach(key => { const task = tasks[key]; if (Array.isArray(task) && task.indexOf(taskName) >= 0) { result.push(key); } }); return result; } return callback[PROMISE_SYMBOL] } var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/; var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/; var FN_ARG_SPLIT = /,/; var FN_ARG = /(=.+)?(\s*)$/; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; function parseParams(func) { const src = func.toString().replace(STRIP_COMMENTS, ''); let match = src.match(FN_ARGS); if (!match) { match = src.match(ARROW_FN_ARGS); } if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src) let [, args] = match; return args .replace(/\s/g, '') .split(FN_ARG_SPLIT) .map((arg) => arg.replace(FN_ARG, '').trim()); } /** * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent * tasks are specified as parameters to the function, after the usual callback * parameter, with the parameter names matching the names of the tasks it * depends on. This can provide even more readable task graphs which can be * easier to maintain. * * If a final callback is specified, the task results are similarly injected, * specified as named parameters after the initial error parameter. * * The autoInject function is purely syntactic sugar and its semantics are * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. * * @name autoInject * @static * @memberOf module:ControlFlow * @method * @see [async.auto]{@link module:ControlFlow.auto} * @category Control Flow * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of * the form 'func([dependencies...], callback). The object's key of a property * serves as the name of the task defined by that property, i.e. can be used * when specifying requirements for other tasks. * * The `callback` parameter is a `callback(err, result)` which must be called * when finished, passing an `error` (which can be `null`) and the result of * the function's execution. The remaining parameters name other tasks on * which the task is dependent, and the results from those tasks are the * arguments of those parameters. * @param {Function} [callback] - An optional callback which is called when all * the tasks have been completed. It receives the `err` argument if any `tasks` * pass an error to their callback, and a `results` object with any completed * task results, similar to `auto`. * @returns {Promise} a promise, if no callback is passed * @example * * // The example from `auto` can be rewritten as follows: * async.autoInject({ * get_data: function(callback) { * // async code to get some data * callback(null, 'data', 'converted to array'); * }, * make_folder: function(callback) { * // async code to create a directory to store a file in * // this is run at the same time as getting the data * callback(null, 'folder'); * }, * write_file: function(get_data, make_folder, callback) { * // once there is some data and the directory exists, * // write the data to a file in the directory * callback(null, 'filename'); * }, * email_link: function(write_file, callback) { * // once the file is written let's email a link to it... * // write_file contains the filename returned by write_file. * callback(null, {'file':write_file, 'email':'user@example.com'}); * } * }, function(err, results) { * console.log('err = ', err); * console.log('email_link = ', results.email_link); * }); * * // If you are using a JS minifier that mangles parameter names, `autoInject` * // will not work with plain functions, since the parameter names will be * // collapsed to a single letter identifier. To work around this, you can * // explicitly specify the names of the parameters your task function needs * // in an array, similar to Angular.js dependency injection. * * // This still has an advantage over plain `auto`, since the results a task * // depends on are still spread into arguments. * async.autoInject({ * //... * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { * callback(null, 'filename'); * }], * email_link: ['write_file', function(write_file, callback) { * callback(null, {'file':write_file, 'email':'user@example.com'}); * }] * //... * }, function(err, results) { * console.log('err = ', err); * console.log('email_link = ', results.email_link); * }); */ function autoInject(tasks, callback) { var newTasks = {}; Object.keys(tasks).forEach(key => { var taskFn = tasks[key]; var params; var fnIsAsync = isAsync(taskFn); var hasNoDeps = (!fnIsAsync && taskFn.length === 1) || (fnIsAsync && taskFn.length === 0); if (Array.isArray(taskFn)) { params = [...taskFn]; taskFn = params.pop(); newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); } else if (hasNoDeps) { // no dependencies, use the function as-is newTasks[key] = taskFn; } else { params = parseParams(taskFn); if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) { throw new Error("autoInject task functions require explicit parameters."); } // remove callback param if (!fnIsAsync) params.pop(); newTasks[key] = params.concat(newTask); } function newTask(results, taskCb) { var newArgs = params.map(name => results[name]); newArgs.push(taskCb); wrapAsync(taskFn)(...newArgs); } }); return auto(newTasks, callback); } // Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation // used for queues. This implementation assumes that the node provided by the user can be modified // to adjust the next and last properties. We implement only the minimal functionality // for queue support. class DLL { constructor() { this.head = this.tail = null; this.length = 0; } removeLink(node) { if (node.prev) node.prev.next = node.next; else this.head = node.next; if (node.next) node.next.prev = node.prev; else this.tail = node.prev; node.prev = node.next = null; this.length -= 1; return node; } empty () { while(this.head) this.shift(); return this; } insertAfter(node, newNode) { newNode.prev = node; newNode.next = node.next; if (node.next) node.next.prev = newNode; else this.tail = newNode; node.next = newNode; this.length += 1; } insertBefore(node, newNode) { newNode.prev = node.prev; newNode.next = node; if (node.prev) node.prev.next = newNode; else this.head = newNode; node.prev = newNode; this.length += 1; } unshift(node) { if (this.head) this.insertBefore(this.head, node); else setInitial(this, node); } push(node) { if (this.tail) this.insertAfter(this.tail, node); else setInitial(this, node); } shift() { return this.head && this.removeLink(this.head); } pop() { return this.tail && this.removeLink(this.tail); } toArray() { return [...this] } *[Symbol.iterator] () { var cur = this.head; while (cur) { yield cur.data; cur = cur.next; } } remove (testFn) { var curr = this.head; while(curr) { var {next} = curr; if (testFn(curr)) { this.removeLink(curr); } curr = next; } return this; } } function setInitial(dll, node) { dll.length = 1; dll.head = dll.tail = node; } function queue(worker, concurrency, payload) { if (concurrency == null) { concurrency = 1; } else if(concurrency === 0) { throw new RangeError('Concurrency must not be zero'); } var _worker = wrapAsync(worker); var numRunning = 0; var workersList = []; const events = { error: [], drain: [], saturated: [], unsaturated: [], empty: [] }; function on (event, handler) { events[event].push(handler); } function once (event, handler) { const handleAndRemove = (...args) => { off(event, handleAndRemove); handler(...args); }; events[event].push(handleAndRemove); } function off (event, handler) { if (!event) return Object.keys(events).forEach(ev => events[ev] = []) if (!handler) return events[event] = [] events[event] = events[event].filter(ev => ev !== handler); } function trigger (event, ...args) { events[event].forEach(handler => handler(...args)); } var processingScheduled = false; function _insert(data, insertAtFront, rejectOnError, callback) { if (callback != null && typeof callback !== 'function') { throw new Error('task callback must be a function'); } q.started = true; var res, rej; function promiseCallback (err, ...args) { // we don't care about the error, let the global error handler // deal with it if (err) return rejectOnError ? rej(err) : res() if (args.length <= 1) return res(args[0]) res(args); } var item = { data, callback: rejectOnError ? promiseCallback : (callback || promiseCallback) }; if (insertAtFront) { q._tasks.unshift(item); } else { q._tasks.push(item); } if (!processingScheduled) { processingScheduled = true; setImmediate$1(() => { processingScheduled = false; q.process(); }); } if (rejectOnError || !callback) { return new Promise((resolve, reject) => { res = resolve; rej = reject; }) } } function _createCB(tasks) { return function (err, ...args) { numRunning -= 1; for (var i = 0, l = tasks.length; i < l; i++) { var task = tasks[i]; var index = workersList.indexOf(task); if (index === 0) { workersList.shift(); } else if (index > 0) { workersList.splice(index, 1); } task.callback(err, ...args); if (err != null) { trigger('error', err, task.data); } } if (numRunning <= (q.concurrency - q.buffer) ) { trigger('unsaturated'); } if (q.idle()) { trigger('drain'); } q.process(); }; } function _maybeDrain(data) { if (data.length === 0 && q.idle()) { // call drain immediately if there are no tasks setImmediate$1(() => trigger('drain')); return true } return false } const eventMethod = (name) => (handler) => { if (!handler) { return new Promise((resolve, reject) => { once(name, (err, data) => { if (err) return reject(err) resolve(data); }); }) } off(name); on(name, handler); }; var isProcessing = false; var q = { _tasks: new DLL(), *[Symbol.iterator] () { yield* q._tasks[Symbol.iterator](); }, concurrency, payload, buffer: concurrency / 4, started: false, paused: false, push (data, callback) { if (Array.isArray(data)) { if (_maybeDrain(data)) return return data.map(datum => _insert(datum, false, false, callback)) } return _insert(data, false, false, callback); }, pushAsync (data, callback) { if (Array.isArray(data)) { if (_maybeDrain(data)) return return data.map(datum => _insert(datum, false, true, callback)) } return _insert(data, false, true, callback); }, kill () { off(); q._tasks.empty(); }, unshift (data, callback) { if (Array.isArray(data)) { if (_maybeDrain(data)) return return data.map(datum => _insert(datum, true, false, callback)) } return _insert(data, true, false, callback); }, unshiftAsync (data, callback) { if (Array.isArray(data)) { if (_maybeDrain(data)) return return data.map(datum => _insert(datum, true, true, callback)) } return _insert(data, true, true, callback); }, remove (testFn) { q._tasks.remove(testFn); }, process () { // Avoid trying to start too many processing operations. This can occur // when callbacks resolve synchronously (#1267). if (isProcessing) { return; } isProcessing = true; while(!q.paused && numRunning < q.concurrency && q._tasks.length){ var tasks = [], data = []; var l = q._tasks.length; if (q.payload) l = Math.min(l, q.payload); for (var i = 0; i < l; i++) { var node = q._tasks.shift(); tasks.push(node); workersList.push(node); data.push(node.data); } numRunning += 1; if (q._tasks.length === 0) { trigger('empty'); } if (numRunning === q.concurrency) { trigger('saturated'); } var cb = onlyOnce(_createCB(tasks)); _worker(data, cb); } isProcessing = false; }, length () { return q._tasks.length; }, running () { return numRunning; }, workersList () { return workersList; }, idle() { return q._tasks.length + numRunning === 0; }, pause () { q.paused = true; }, resume () { if (q.paused === false) { return; } q.paused = false; setImmediate$1(q.process); } }; // define these as fixed properties, so people get useful errors when updating Object.defineProperties(q, { saturated: { writable: false, value: eventMethod('saturated') }, unsaturated: { writable: false, value: eventMethod('unsaturated') }, empty: { writable: false, value: eventMethod('empty') }, drain: { writable: false, value: eventMethod('drain') }, error: { writable: false, value: eventMethod('error') }, }); return q; } /** * Creates a `cargo` object with the specified payload. Tasks added to the * cargo will be processed altogether (up to the `payload` limit). If the * `worker` is in progress, the task is queued until it becomes available. Once * the `worker` has completed some tasks, each callback of those tasks is * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) * for how `cargo` and `queue` work. * * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers * at a time, cargo passes an array of tasks to a single worker, repeating * when the worker is finished. * * @name cargo * @static * @memberOf module:ControlFlow * @method * @see [async.queue]{@link module:ControlFlow.queue} * @category Control Flow * @param {AsyncFunction} worker - An asynchronous function for processing an array * of queued tasks. Invoked with `(tasks, callback)`. * @param {number} [payload=Infinity] - An optional `integer` for determining * how many tasks should be processed per round; if omitted, the default is * unlimited. * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the cargo and inner queue. * @example * * // create a cargo object with payload 2 * var cargo = async.cargo(function(tasks, callback) { * for (var i=0; i { _iteratee(memo, x, (err, v) => { memo = v; iterCb(err); }); }, err => callback(err, memo)); } var reduce$1 = awaitify(reduce, 4); /** * Version of the compose function that is more natural to read. Each function * consumes the return value of the previous function. It is the equivalent of * [compose]{@link module:ControlFlow.compose} with the arguments reversed. * * Each function is executed with the `this` binding of the composed function. * * @name seq * @static * @memberOf module:ControlFlow * @method * @see [async.compose]{@link module:ControlFlow.compose} * @category Control Flow * @param {...AsyncFunction} functions - the asynchronous functions to compose * @returns {Function} a function that composes the `functions` in order * @example * * // Requires lodash (or underscore), express3 and dresende's orm2. * // Part of an app, that fetches cats of the logged user. * // This example uses `seq` function to avoid overnesting and error * // handling clutter. * app.get('/cats', function(request, response) { * var User = request.models.User; * async.seq( * _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) * function(user, fn) { * user.getCats(fn); // 'getCats' has signature (callback(err, data)) * } * )(req.session.user_id, function (err, cats) { * if (err) { * console.error(err); * response.json({ status: 'error', message: err.message }); * } else { * response.json({ status: 'ok', message: 'Cats found', data: cats }); * } * }); * }); */ function seq(...functions) { var _functions = functions.map(wrapAsync); return function (...args) { var that = this; var cb = args[args.length - 1]; if (typeof cb == 'function') { args.pop(); } else { cb = promiseCallback(); } reduce$1(_functions, args, (newargs, fn, iterCb) => { fn.apply(that, newargs.concat((err, ...nextargs) => { iterCb(err, nextargs); })); }, (err, results) => cb(err, ...results)); return cb[PROMISE_SYMBOL] }; } /** * Creates a function which is a composition of the passed asynchronous * functions. Each function consumes the return value of the function that * follows. Composing functions `f()`, `g()`, and `h()` would produce the result * of `f(g(h()))`, only this version uses callbacks to obtain the return values. * * If the last argument to the composed function is not a function, a promise * is returned when you call it. * * Each function is executed with the `this` binding of the composed function. * * @name compose * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {...AsyncFunction} functions - the asynchronous functions to compose * @returns {Function} an asynchronous function that is the composed * asynchronous `functions` * @example * * function add1(n, callback) { * setTimeout(function () { * callback(null, n + 1); * }, 10); * } * * function mul3(n, callback) { * setTimeout(function () { * callback(null, n * 3); * }, 10); * } * * var add1mul3 = async.compose(mul3, add1); * add1mul3(4, function (err, result) { * // result now equals 15 * }); */ function compose(...args) { return seq(...args.reverse()); } /** * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. * * @name mapLimit * @static * @memberOf module:Collections * @method * @see [async.map]{@link module:Collections.map} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with the transformed item. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Results is an array of the * transformed items from the `coll`. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed */ function mapLimit (coll, limit, iteratee, callback) { return _asyncMap(eachOfLimit(limit), coll, iteratee, callback) } var mapLimit$1 = awaitify(mapLimit, 4); /** * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time. * * @name concatLimit * @static * @memberOf module:Collections * @method * @see [async.concat]{@link module:Collections.concat} * @category Collection * @alias flatMapLimit * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, * which should use an array as its result. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished, or an error occurs. Results is an array * containing the concatenated results of the `iteratee` function. Invoked with * (err, results). * @returns A Promise, if no callback is passed */ function concatLimit(coll, limit, iteratee, callback) { var _iteratee = wrapAsync(iteratee); return mapLimit$1(coll, limit, (val, iterCb) => { _iteratee(val, (err, ...args) => { if (err) return iterCb(err); return iterCb(err, args); }); }, (err, mapResults) => { var result = []; for (var i = 0; i < mapResults.length; i++) { if (mapResults[i]) { result = result.concat(...mapResults[i]); } } return callback(err, result); }); } var concatLimit$1 = awaitify(concatLimit, 4); /** * Applies `iteratee` to each item in `coll`, concatenating the results. Returns * the concatenated list. The `iteratee`s are called in parallel, and the * results are concatenated as they return. The results array will be returned in * the original order of `coll` passed to the `iteratee` function. * * @name concat * @static * @memberOf module:Collections * @method * @category Collection * @alias flatMap * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, * which should use an array as its result. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished, or an error occurs. Results is an array * containing the concatenated results of the `iteratee` function. Invoked with * (err, results). * @returns A Promise, if no callback is passed * @example * * async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) { * // files is now a list of filenames that exist in the 3 directories * }); */ function concat(coll, iteratee, callback) { return concatLimit$1(coll, Infinity, iteratee, callback) } var concat$1 = awaitify(concat, 3); /** * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. * * @name concatSeries * @static * @memberOf module:Collections * @method * @see [async.concat]{@link module:Collections.concat} * @category Collection * @alias flatMapSeries * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. * The iteratee should complete with an array an array of results. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished, or an error occurs. Results is an array * containing the concatenated results of the `iteratee` function. Invoked with * (err, results). * @returns A Promise, if no callback is passed */ function concatSeries(coll, iteratee, callback) { return concatLimit$1(coll, 1, iteratee, callback) } var concatSeries$1 = awaitify(concatSeries, 3); /** * Returns a function that when called, calls-back with the values provided. * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to * [`auto`]{@link module:ControlFlow.auto}. * * @name constant * @static * @memberOf module:Utils * @method * @category Util * @param {...*} arguments... - Any number of arguments to automatically invoke * callback with. * @returns {AsyncFunction} Returns a function that when invoked, automatically * invokes the callback with the previous given arguments. * @example * * async.waterfall([ * async.constant(42), * function (value, next) { * // value === 42 * }, * //... * ], callback); * * async.waterfall([ * async.constant(filename, "utf8"), * fs.readFile, * function (fileData, next) { * //... * } * //... * ], callback); * * async.auto({ * hostname: async.constant("https://server.net/"), * port: findFreePort, * launchServer: ["hostname", "port", function (options, cb) { * startServer(options, cb); * }], * //... * }, callback); */ function constant(...args) { return function (...ignoredArgs/*, callback*/) { var callback = ignoredArgs.pop(); return callback(null, ...args); }; } function _createTester(check, getResult) { return (eachfn, arr, _iteratee, cb) => { var testPassed = false; var testResult; const iteratee = wrapAsync(_iteratee); eachfn(arr, (value, _, callback) => { iteratee(value, (err, result) => { if (err || err === false) return callback(err); if (check(result) && !testResult) { testPassed = true; testResult = getResult(true, value); return callback(null, breakLoop); } callback(); }); }, err => { if (err) return cb(err); cb(null, testPassed ? testResult : getResult(false)); }); }; } /** * Returns the first value in `coll` that passes an async truth test. The * `iteratee` is applied in parallel, meaning the first iteratee to return * `true` will fire the detect `callback` with that result. That means the * result might not be the first item in the original `coll` (in terms of order) * that passes the test. * If order within the original `coll` is important, then look at * [`detectSeries`]{@link module:Collections.detectSeries}. * * @name detect * @static * @memberOf module:Collections * @method * @alias find * @category Collections * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. * The iteratee must complete with a boolean value as its result. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the `iteratee` functions have finished. * Result will be the first item in the array that passes the truth test * (iteratee) or the value `undefined` if none passed. Invoked with * (err, result). * @returns A Promise, if no callback is passed * @example * * async.detect(['file1','file2','file3'], function(filePath, callback) { * fs.access(filePath, function(err) { * callback(null, !err) * }); * }, function(err, result) { * // result now equals the first file in the list that exists * }); */ function detect(coll, iteratee, callback) { return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback) } var detect$1 = awaitify(detect, 3); /** * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a * time. * * @name detectLimit * @static * @memberOf module:Collections * @method * @see [async.detect]{@link module:Collections.detect} * @alias findLimit * @category Collections * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. * The iteratee must complete with a boolean value as its result. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the `iteratee` functions have finished. * Result will be the first item in the array that passes the truth test * (iteratee) or the value `undefined` if none passed. Invoked with * (err, result). * @returns a Promise if no callback is passed */ function detectLimit(coll, limit, iteratee, callback) { return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback) } var detectLimit$1 = awaitify(detectLimit, 4); /** * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. * * @name detectSeries * @static * @memberOf module:Collections * @method * @see [async.detect]{@link module:Collections.detect} * @alias findSeries * @category Collections * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. * The iteratee must complete with a boolean value as its result. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the `iteratee` functions have finished. * Result will be the first item in the array that passes the truth test * (iteratee) or the value `undefined` if none passed. Invoked with * (err, result). * @returns a Promise if no callback is passed */ function detectSeries(coll, iteratee, callback) { return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback) } var detectSeries$1 = awaitify(detectSeries, 3); function consoleFunc(name) { return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => { if (typeof console === 'object') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { resultArgs.forEach(x => console[name](x)); } } }) } /** * Logs the result of an [`async` function]{@link AsyncFunction} to the * `console` using `console.dir` to display the properties of the resulting object. * Only works in Node.js or in browsers that support `console.dir` and * `console.error` (such as FF and Chrome). * If multiple arguments are returned from the async function, * `console.dir` is called on each argument in order. * * @name dir * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} function - The function you want to eventually apply * all arguments to. * @param {...*} arguments... - Any number of arguments to apply to the function. * @example * * // in a module * var hello = function(name, callback) { * setTimeout(function() { * callback(null, {hello: name}); * }, 1000); * }; * * // in the node repl * node> async.dir(hello, 'world'); * {hello: 'world'} */ var dir = consoleFunc('dir'); /** * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in * the order of operations, the arguments `test` and `iteratee` are switched. * * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. * * @name doWhilst * @static * @memberOf module:ControlFlow * @method * @see [async.whilst]{@link module:ControlFlow.whilst} * @category Control Flow * @param {AsyncFunction} iteratee - A function which is called each time `test` * passes. Invoked with (callback). * @param {AsyncFunction} test - asynchronous truth test to perform after each * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the * non-error args from the previous callback of `iteratee`. * @param {Function} [callback] - A callback which is called after the test * function has failed and repeated execution of `iteratee` has stopped. * `callback` will be passed an error and any arguments passed to the final * `iteratee`'s callback. Invoked with (err, [results]); * @returns {Promise} a promise, if no callback is passed */ function doWhilst(iteratee, test, callback) { callback = onlyOnce(callback); var _fn = wrapAsync(iteratee); var _test = wrapAsync(test); var results; function next(err, ...args) { if (err) return callback(err); if (err === false) return; results = args; _test(...args, check); } function check(err, truth) { if (err) return callback(err); if (err === false) return; if (!truth) return callback(null, ...results); _fn(next); } return check(null, true); } var doWhilst$1 = awaitify(doWhilst, 3); /** * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the * argument ordering differs from `until`. * * @name doUntil * @static * @memberOf module:ControlFlow * @method * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} * @category Control Flow * @param {AsyncFunction} iteratee - An async function which is called each time * `test` fails. Invoked with (callback). * @param {AsyncFunction} test - asynchronous truth test to perform after each * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the * non-error args from the previous callback of `iteratee` * @param {Function} [callback] - A callback which is called after the test * function has passed and repeated execution of `iteratee` has stopped. `callback` * will be passed an error and any arguments passed to the final `iteratee`'s * callback. Invoked with (err, [results]); * @returns {Promise} a promise, if no callback is passed */ function doUntil(iteratee, test, callback) { const _test = wrapAsync(test); return doWhilst$1(iteratee, (...args) => { const cb = args.pop(); _test(...args, (err, truth) => cb (err, !truth)); }, callback); } function _withoutIndex(iteratee) { return (value, index, callback) => iteratee(value, callback); } /** * Applies the function `iteratee` to each item in `coll`, in parallel. * The `iteratee` is called with an item from the list, and a callback for when * it has finished. If the `iteratee` passes an error to its `callback`, the * main `callback` (for the `each` function) is immediately called with the * error. * * Note, that since this function applies `iteratee` to each item in parallel, * there is no guarantee that the iteratee functions will complete in order. * * @name each * @static * @memberOf module:Collections * @method * @alias forEach * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to * each item in `coll`. Invoked with (item, callback). * The array index is not passed to the iteratee. * If you need the index, use `eachOf`. * @param {Function} [callback] - A callback which is called when all * `iteratee` functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted * @example * * // assuming openFiles is an array of file names and saveFile is a function * // to save the modified contents of that file: * * async.each(openFiles, saveFile, function(err){ * // if any of the saves produced an error, err would equal that error * }); * * // assuming openFiles is an array of file names * async.each(openFiles, function(file, callback) { * * // Perform operation on file here. * console.log('Processing file ' + file); * * if( file.length > 32 ) { * console.log('This file name is too long'); * callback('File name too long'); * } else { * // Do work to process file here * console.log('File processed'); * callback(); * } * }, function(err) { * // if any of the file processing produced an error, err would equal that error * if( err ) { * // One of the iterations produced an error. * // All processing will now stop. * console.log('A file failed to process'); * } else { * console.log('All files have been processed successfully'); * } * }); */ function eachLimit(coll, iteratee, callback) { return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback); } var each = awaitify(eachLimit, 3); /** * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. * * @name eachLimit * @static * @memberOf module:Collections * @method * @see [async.each]{@link module:Collections.each} * @alias forEachLimit * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The array index is not passed to the iteratee. * If you need the index, use `eachOfLimit`. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all * `iteratee` functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted */ function eachLimit$1(coll, limit, iteratee, callback) { return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback); } var eachLimit$2 = awaitify(eachLimit$1, 4); /** * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. * * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item * in series and therefore the iteratee functions will complete in order. * @name eachSeries * @static * @memberOf module:Collections * @method * @see [async.each]{@link module:Collections.each} * @alias forEachSeries * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each * item in `coll`. * The array index is not passed to the iteratee. * If you need the index, use `eachOfSeries`. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all * `iteratee` functions have finished, or an error occurs. Invoked with (err). * @returns {Promise} a promise, if a callback is omitted */ function eachSeries(coll, iteratee, callback) { return eachLimit$2(coll, 1, iteratee, callback) } var eachSeries$1 = awaitify(eachSeries, 3); /** * Wrap an async function and ensure it calls its callback on a later tick of * the event loop. If the function already calls its callback on a next tick, * no extra deferral is added. This is useful for preventing stack overflows * (`RangeError: Maximum call stack size exceeded`) and generally keeping * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) * contained. ES2017 `async` functions are returned as-is -- they are immune * to Zalgo's corrupting influences, as they always resolve on a later tick. * * @name ensureAsync * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} fn - an async function, one that expects a node-style * callback as its last argument. * @returns {AsyncFunction} Returns a wrapped function with the exact same call * signature as the function passed in. * @example * * function sometimesAsync(arg, callback) { * if (cache[arg]) { * return callback(null, cache[arg]); // this would be synchronous!! * } else { * doSomeIO(arg, callback); // this IO would be asynchronous * } * } * * // this has a risk of stack overflows if many results are cached in a row * async.mapSeries(args, sometimesAsync, done); * * // this will defer sometimesAsync's callback if necessary, * // preventing stack overflows * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); */ function ensureAsync(fn) { if (isAsync(fn)) return fn; return function (...args/*, callback*/) { var callback = args.pop(); var sync = true; args.push((...innerArgs) => { if (sync) { setImmediate$1(() => callback(...innerArgs)); } else { callback(...innerArgs); } }); fn.apply(this, args); sync = false; }; } /** * Returns `true` if every element in `coll` satisfies an async test. If any * iteratee call returns `false`, the main `callback` is immediately called. * * @name every * @static * @memberOf module:Collections * @method * @alias all * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collection in parallel. * The iteratee must complete with a boolean result value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Result will be either `true` or `false` * depending on the values of the async tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided * @example * * async.every(['file1','file2','file3'], function(filePath, callback) { * fs.access(filePath, function(err) { * callback(null, !err) * }); * }, function(err, result) { * // if result is true then every file exists * }); */ function every(coll, iteratee, callback) { return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback) } var every$1 = awaitify(every, 3); /** * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. * * @name everyLimit * @static * @memberOf module:Collections * @method * @see [async.every]{@link module:Collections.every} * @alias allLimit * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collection in parallel. * The iteratee must complete with a boolean result value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Result will be either `true` or `false` * depending on the values of the async tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided */ function everyLimit(coll, limit, iteratee, callback) { return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback) } var everyLimit$1 = awaitify(everyLimit, 4); /** * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. * * @name everySeries * @static * @memberOf module:Collections * @method * @see [async.every]{@link module:Collections.every} * @alias allSeries * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collection in series. * The iteratee must complete with a boolean result value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Result will be either `true` or `false` * depending on the values of the async tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided */ function everySeries(coll, iteratee, callback) { return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback) } var everySeries$1 = awaitify(everySeries, 3); function filterArray(eachfn, arr, iteratee, callback) { var truthValues = new Array(arr.length); eachfn(arr, (x, index, iterCb) => { iteratee(x, (err, v) => { truthValues[index] = !!v; iterCb(err); }); }, err => { if (err) return callback(err); var results = []; for (var i = 0; i < arr.length; i++) { if (truthValues[i]) results.push(arr[i]); } callback(null, results); }); } function filterGeneric(eachfn, coll, iteratee, callback) { var results = []; eachfn(coll, (x, index, iterCb) => { iteratee(x, (err, v) => { if (err) return iterCb(err); if (v) { results.push({index, value: x}); } iterCb(err); }); }, err => { if (err) return callback(err); callback(null, results .sort((a, b) => a.index - b.index) .map(v => v.value)); }); } function _filter(eachfn, coll, iteratee, callback) { var filter = isArrayLike(coll) ? filterArray : filterGeneric; return filter(eachfn, coll, wrapAsync(iteratee), callback); } /** * Returns a new array of all the values in `coll` which pass an async truth * test. This operation is performed in parallel, but the results array will be * in the same order as the original. * * @name filter * @static * @memberOf module:Collections * @method * @alias select * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. * The `iteratee` is passed a `callback(err, truthValue)`, which must be called * with a boolean argument once it has completed. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results). * @returns {Promise} a promise, if no callback provided * @example * * async.filter(['file1','file2','file3'], function(filePath, callback) { * fs.access(filePath, function(err) { * callback(null, !err) * }); * }, function(err, results) { * // results now equals an array of the existing files * }); */ function filter (coll, iteratee, callback) { return _filter(eachOf$1, coll, iteratee, callback) } var filter$1 = awaitify(filter, 3); /** * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a * time. * * @name filterLimit * @static * @memberOf module:Collections * @method * @see [async.filter]{@link module:Collections.filter} * @alias selectLimit * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {Function} iteratee - A truth test to apply to each item in `coll`. * The `iteratee` is passed a `callback(err, truthValue)`, which must be called * with a boolean argument once it has completed. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results). * @returns {Promise} a promise, if no callback provided */ function filterLimit (coll, limit, iteratee, callback) { return _filter(eachOfLimit(limit), coll, iteratee, callback) } var filterLimit$1 = awaitify(filterLimit, 4); /** * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. * * @name filterSeries * @static * @memberOf module:Collections * @method * @see [async.filter]{@link module:Collections.filter} * @alias selectSeries * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. * The `iteratee` is passed a `callback(err, truthValue)`, which must be called * with a boolean argument once it has completed. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results) * @returns {Promise} a promise, if no callback provided */ function filterSeries (coll, iteratee, callback) { return _filter(eachOfSeries$1, coll, iteratee, callback) } var filterSeries$1 = awaitify(filterSeries, 3); /** * Calls the asynchronous function `fn` with a callback parameter that allows it * to call itself again, in series, indefinitely. * If an error is passed to the callback then `errback` is called with the * error, and execution stops, otherwise it will never be called. * * @name forever * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {AsyncFunction} fn - an async function to call repeatedly. * Invoked with (next). * @param {Function} [errback] - when `fn` passes an error to it's callback, * this function will be called, and execution stops. Invoked with (err). * @returns {Promise} a promise that rejects if an error occurs and an errback * is not passed * @example * * async.forever( * function(next) { * // next is suitable for passing to things that need a callback(err [, whatever]); * // it will result in this function being called again. * }, * function(err) { * // if next is called with a value in its first parameter, it will appear * // in here as 'err', and execution will stop. * } * ); */ function forever(fn, errback) { var done = onlyOnce(errback); var task = wrapAsync(ensureAsync(fn)); function next(err) { if (err) return done(err); if (err === false) return; task(next); } return next(); } var forever$1 = awaitify(forever, 2); /** * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. * * @name groupByLimit * @static * @memberOf module:Collections * @method * @see [async.groupBy]{@link module:Collections.groupBy} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with a `key` to group the value under. * Invoked with (value, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Result is an `Object` whoses * properties are arrays of values which returned the corresponding key. * @returns {Promise} a promise, if no callback is passed */ function groupByLimit(coll, limit, iteratee, callback) { var _iteratee = wrapAsync(iteratee); return mapLimit$1(coll, limit, (val, iterCb) => { _iteratee(val, (err, key) => { if (err) return iterCb(err); return iterCb(err, {key, val}); }); }, (err, mapResults) => { var result = {}; // from MDN, handle object having an `hasOwnProperty` prop var {hasOwnProperty} = Object.prototype; for (var i = 0; i < mapResults.length; i++) { if (mapResults[i]) { var {key} = mapResults[i]; var {val} = mapResults[i]; if (hasOwnProperty.call(result, key)) { result[key].push(val); } else { result[key] = [val]; } } } return callback(err, result); }); } var groupByLimit$1 = awaitify(groupByLimit, 4); /** * Returns a new object, where each value corresponds to an array of items, from * `coll`, that returned the corresponding key. That is, the keys of the object * correspond to the values passed to the `iteratee` callback. * * Note: Since this function applies the `iteratee` to each item in parallel, * there is no guarantee that the `iteratee` functions will complete in order. * However, the values for each key in the `result` will be in the same order as * the original `coll`. For Objects, the values will roughly be in the order of * the original Objects' keys (but this can vary across JavaScript engines). * * @name groupBy * @static * @memberOf module:Collections * @method * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with a `key` to group the value under. * Invoked with (value, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Result is an `Object` whoses * properties are arrays of values which returned the corresponding key. * @returns {Promise} a promise, if no callback is passed * @example * * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) { * db.findById(userId, function(err, user) { * if (err) return callback(err); * return callback(null, user.age); * }); * }, function(err, result) { * // result is object containing the userIds grouped by age * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']}; * }); */ function groupBy (coll, iteratee, callback) { return groupByLimit$1(coll, Infinity, iteratee, callback) } /** * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. * * @name groupBySeries * @static * @memberOf module:Collections * @method * @see [async.groupBy]{@link module:Collections.groupBy} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with a `key` to group the value under. * Invoked with (value, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. Result is an `Object` whoses * properties are arrays of values which returned the corresponding key. * @returns {Promise} a promise, if no callback is passed */ function groupBySeries (coll, iteratee, callback) { return groupByLimit$1(coll, 1, iteratee, callback) } /** * Logs the result of an `async` function to the `console`. Only works in * Node.js or in browsers that support `console.log` and `console.error` (such * as FF and Chrome). If multiple arguments are returned from the async * function, `console.log` is called on each argument in order. * * @name log * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} function - The function you want to eventually apply * all arguments to. * @param {...*} arguments... - Any number of arguments to apply to the function. * @example * * // in a module * var hello = function(name, callback) { * setTimeout(function() { * callback(null, 'hello ' + name); * }, 1000); * }; * * // in the node repl * node> async.log(hello, 'world'); * 'hello world' */ var log = consoleFunc('log'); /** * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a * time. * * @name mapValuesLimit * @static * @memberOf module:Collections * @method * @see [async.mapValues]{@link module:Collections.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - A function to apply to each value and key * in `coll`. * The iteratee should complete with the transformed value as its result. * Invoked with (value, key, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. `result` is a new object consisting * of each key from `obj`, with each transformed value on the right-hand side. * Invoked with (err, result). * @returns {Promise} a promise, if no callback is passed */ function mapValuesLimit(obj, limit, iteratee, callback) { callback = once(callback); var newObj = {}; var _iteratee = wrapAsync(iteratee); return eachOfLimit(limit)(obj, (val, key, next) => { _iteratee(val, key, (err, result) => { if (err) return next(err); newObj[key] = result; next(err); }); }, err => callback(err, newObj)); } var mapValuesLimit$1 = awaitify(mapValuesLimit, 4); /** * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. * * Produces a new Object by mapping each value of `obj` through the `iteratee` * function. The `iteratee` is called each `value` and `key` from `obj` and a * callback for when it has finished processing. Each of these callbacks takes * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` * passes an error to its callback, the main `callback` (for the `mapValues` * function) is immediately called with the error. * * Note, the order of the keys in the result is not guaranteed. The keys will * be roughly in the order they complete, (but this is very engine-specific) * * @name mapValues * @static * @memberOf module:Collections * @method * @category Collection * @param {Object} obj - A collection to iterate over. * @param {AsyncFunction} iteratee - A function to apply to each value and key * in `coll`. * The iteratee should complete with the transformed value as its result. * Invoked with (value, key, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. `result` is a new object consisting * of each key from `obj`, with each transformed value on the right-hand side. * Invoked with (err, result). * @returns {Promise} a promise, if no callback is passed * @example * * async.mapValues({ * f1: 'file1', * f2: 'file2', * f3: 'file3' * }, function (file, key, callback) { * fs.stat(file, callback); * }, function(err, result) { * // result is now a map of stats for each file, e.g. * // { * // f1: [stats for file1], * // f2: [stats for file2], * // f3: [stats for file3] * // } * }); */ function mapValues(obj, iteratee, callback) { return mapValuesLimit$1(obj, Infinity, iteratee, callback) } /** * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. * * @name mapValuesSeries * @static * @memberOf module:Collections * @method * @see [async.mapValues]{@link module:Collections.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {AsyncFunction} iteratee - A function to apply to each value and key * in `coll`. * The iteratee should complete with the transformed value as its result. * Invoked with (value, key, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` * functions have finished, or an error occurs. `result` is a new object consisting * of each key from `obj`, with each transformed value on the right-hand side. * Invoked with (err, result). * @returns {Promise} a promise, if no callback is passed */ function mapValuesSeries(obj, iteratee, callback) { return mapValuesLimit$1(obj, 1, iteratee, callback) } /** * Caches the results of an async function. When creating a hash to store * function results against, the callback is omitted from the hash and an * optional hash function can be used. * * **Note: if the async function errs, the result will not be cached and * subsequent calls will call the wrapped function.** * * If no hash function is specified, the first argument is used as a hash key, * which may work reasonably if it is a string or a data type that converts to a * distinct string. Note that objects and arrays will not behave reasonably. * Neither will cases where the other arguments are significant. In such cases, * specify your own hash function. * * The cache of results is exposed as the `memo` property of the function * returned by `memoize`. * * @name memoize * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} fn - The async function to proxy and cache results from. * @param {Function} hasher - An optional function for generating a custom hash * for storing results. It has all the arguments applied to it apart from the * callback, and must be synchronous. * @returns {AsyncFunction} a memoized version of `fn` * @example * * var slow_fn = function(name, callback) { * // do something * callback(null, result); * }; * var fn = async.memoize(slow_fn); * * // fn can now be used as if it were slow_fn * fn('some name', function() { * // callback * }); */ function memoize(fn, hasher = v => v) { var memo = Object.create(null); var queues = Object.create(null); var _fn = wrapAsync(fn); var memoized = initialParams((args, callback) => { var key = hasher(...args); if (key in memo) { setImmediate$1(() => callback(null, ...memo[key])); } else if (key in queues) { queues[key].push(callback); } else { queues[key] = [callback]; _fn(...args, (err, ...resultArgs) => { // #1465 don't memoize if an error occurred if (!err) { memo[key] = resultArgs; } var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i](err, ...resultArgs); } }); } }); memoized.memo = memo; memoized.unmemoized = fn; return memoized; } /** * Calls `callback` on a later loop around the event loop. In Node.js this just * calls `process.nextTick`. In the browser it will use `setImmediate` if * available, otherwise `setTimeout(callback, 0)`, which means other higher * priority events may precede the execution of `callback`. * * This is used internally for browser-compatibility purposes. * * @name nextTick * @static * @memberOf module:Utils * @method * @see [async.setImmediate]{@link module:Utils.setImmediate} * @category Util * @param {Function} callback - The function to call on a later loop around * the event loop. Invoked with (args...). * @param {...*} args... - any number of additional arguments to pass to the * callback on the next tick. * @example * * var call_order = []; * async.nextTick(function() { * call_order.push('two'); * // call_order now equals ['one','two'] * }); * call_order.push('one'); * * async.setImmediate(function (a, b, c) { * // a, b, and c equal 1, 2, and 3 * }, 1, 2, 3); */ var _defer$1; if (hasNextTick) { _defer$1 = process.nextTick; } else if (hasSetImmediate) { _defer$1 = setImmediate; } else { _defer$1 = fallback; } var nextTick = wrap(_defer$1); var _parallel = awaitify((eachfn, tasks, callback) => { var results = isArrayLike(tasks) ? [] : {}; eachfn(tasks, (task, key, taskCb) => { wrapAsync(task)((err, ...result) => { if (result.length < 2) { [result] = result; } results[key] = result; taskCb(err); }); }, err => callback(err, results)); }, 3); /** * Run the `tasks` collection of functions in parallel, without waiting until * the previous function has completed. If any of the functions pass an error to * its callback, the main `callback` is immediately called with the value of the * error. Once the `tasks` have completed, the results are passed to the final * `callback` as an array. * * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about * parallel execution of code. If your tasks do not use any timers or perform * any I/O, they will actually be executed in series. Any synchronous setup * sections for each task will happen one after the other. JavaScript remains * single-threaded. * * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the * execution of other tasks when a task fails. * * It is also possible to use an object instead of an array. Each property will * be run as a function and the results will be passed to the final `callback` * as an object instead of an array. This can be a more readable way of handling * results from {@link async.parallel}. * * @name parallel * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of * [async functions]{@link AsyncFunction} to run. * Each async function can complete with any number of optional `result` values. * @param {Function} [callback] - An optional callback to run once all the * functions have completed successfully. This function gets a results array * (or object) containing all the result arguments passed to the task callbacks. * Invoked with (err, results). * @returns {Promise} a promise, if a callback is not passed * * @example * async.parallel([ * function(callback) { * setTimeout(function() { * callback(null, 'one'); * }, 200); * }, * function(callback) { * setTimeout(function() { * callback(null, 'two'); * }, 100); * } * ], * // optional callback * function(err, results) { * // the results array will equal ['one','two'] even though * // the second function had a shorter timeout. * }); * * // an example using an object instead of an array * async.parallel({ * one: function(callback) { * setTimeout(function() { * callback(null, 1); * }, 200); * }, * two: function(callback) { * setTimeout(function() { * callback(null, 2); * }, 100); * } * }, function(err, results) { * // results is now equals to: {one: 1, two: 2} * }); */ function parallel(tasks, callback) { return _parallel(eachOf$1, tasks, callback); } /** * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a * time. * * @name parallelLimit * @static * @memberOf module:ControlFlow * @method * @see [async.parallel]{@link module:ControlFlow.parallel} * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of * [async functions]{@link AsyncFunction} to run. * Each async function can complete with any number of optional `result` values. * @param {number} limit - The maximum number of async operations at a time. * @param {Function} [callback] - An optional callback to run once all the * functions have completed successfully. This function gets a results array * (or object) containing all the result arguments passed to the task callbacks. * Invoked with (err, results). * @returns {Promise} a promise, if a callback is not passed */ function parallelLimit(tasks, limit, callback) { return _parallel(eachOfLimit(limit), tasks, callback); } /** * A queue of tasks for the worker function to complete. * @typedef {Iterable} QueueObject * @memberOf module:ControlFlow * @property {Function} length - a function returning the number of items * waiting to be processed. Invoke with `queue.length()`. * @property {boolean} started - a boolean indicating whether or not any * items have been pushed and processed by the queue. * @property {Function} running - a function returning the number of items * currently being processed. Invoke with `queue.running()`. * @property {Function} workersList - a function returning the array of items * currently being processed. Invoke with `queue.workersList()`. * @property {Function} idle - a function returning false if there are items * waiting or being processed, or true if not. Invoke with `queue.idle()`. * @property {number} concurrency - an integer for determining how many `worker` * functions should be run in parallel. This property can be changed after a * `queue` is created to alter the concurrency on-the-fly. * @property {number} payload - an integer that specifies how many items are * passed to the worker function at a time. only applies if this is a * [cargo]{@link module:ControlFlow.cargo} object * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback` * once the `worker` has finished processing the task. Instead of a single task, * a `tasks` array can be submitted. The respective callback is used for every * task in the list. Invoke with `queue.push(task, [callback])`, * @property {AsyncFunction} unshift - add a new task to the front of the `queue`. * Invoke with `queue.unshift(task, [callback])`. * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns * a promise that rejects if an error occurs. * @property {AsyncFunction} unshirtAsync - the same as `q.unshift`, except this returns * a promise that rejects if an error occurs. * @property {Function} remove - remove items from the queue that match a test * function. The test function will be passed an object with a `data` property, * and a `priority` property, if this is a * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. * Invoked with `queue.remove(testFn)`, where `testFn` is of the form * `function ({data, priority}) {}` and returns a Boolean. * @property {Function} saturated - a function that sets a callback that is * called when the number of running workers hits the `concurrency` limit, and * further tasks will be queued. If the callback is omitted, `q.saturated()` * returns a promise for the next occurrence. * @property {Function} unsaturated - a function that sets a callback that is * called when the number of running workers is less than the `concurrency` & * `buffer` limits, and further tasks will not be queued. If the callback is * omitted, `q.unsaturated()` returns a promise for the next occurrence. * @property {number} buffer - A minimum threshold buffer in order to say that * the `queue` is `unsaturated`. * @property {Function} empty - a function that sets a callback that is called * when the last item from the `queue` is given to a `worker`. If the callback * is omitted, `q.empty()` returns a promise for the next occurrence. * @property {Function} drain - a function that sets a callback that is called * when the last item from the `queue` has returned from the `worker`. If the * callback is omitted, `q.drain()` returns a promise for the next occurrence. * @property {Function} error - a function that sets a callback that is called * when a task errors. Has the signature `function(error, task)`. If the * callback is omitted, `error()` returns a promise that rejects on the next * error. * @property {boolean} paused - a boolean for determining whether the queue is * in a paused state. * @property {Function} pause - a function that pauses the processing of tasks * until `resume()` is called. Invoke with `queue.pause()`. * @property {Function} resume - a function that resumes the processing of * queued tasks when the queue is paused. Invoke with `queue.resume()`. * @property {Function} kill - a function that removes the `drain` callback and * empties remaining tasks from the queue forcing it to go idle. No more tasks * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. * * @example * const q = aync.queue(worker, 2) * q.push(item1) * q.push(item2) * q.push(item3) * // queues are iterable, spread into an array to inspect * const items = [...q] // [item1, item2, item3] * // or use for of * for (let item of q) { * console.log(item) * } * * q.drain(() => { * console.log('all done') * }) * // or * await q.drain() */ /** * Creates a `queue` object with the specified `concurrency`. Tasks added to the * `queue` are processed in parallel (up to the `concurrency` limit). If all * `worker`s are in progress, the task is queued until one becomes available. * Once a `worker` completes a `task`, that `task`'s callback is called. * * @name queue * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {AsyncFunction} worker - An async function for processing a queued task. * If you want to handle errors from an individual task, pass a callback to * `q.push()`. Invoked with (task, callback). * @param {number} [concurrency=1] - An `integer` for determining how many * `worker` functions should be run in parallel. If omitted, the concurrency * defaults to `1`. If the concurrency is `0`, an error is thrown. * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be * attached as certain properties to listen for specific events during the * lifecycle of the queue. * @example * * // create a queue object with concurrency 2 * var q = async.queue(function(task, callback) { * console.log('hello ' + task.name); * callback(); * }, 2); * * // assign a callback * q.drain(function() { * console.log('all items have been processed'); * }); * // or await the end * await q.drain() * * // assign an error callback * q.error(function(err, task) { * console.error('task experienced an error'); * }); * * // add some items to the queue * q.push({name: 'foo'}, function(err) { * console.log('finished processing foo'); * }); * // callback is optional * q.push({name: 'bar'}); * * // add some items to the queue (batch-wise) * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { * console.log('finished processing item'); * }); * * // add some items to the front of the queue * q.unshift({name: 'bar'}, function (err) { * console.log('finished processing bar'); * }); */ function queue$1 (worker, concurrency) { var _worker = wrapAsync(worker); return queue((items, cb) => { _worker(items[0], cb); }, concurrency, 1); } // Binary min-heap implementation used for priority queue. // Implementation is stable, i.e. push time is considered for equal priorities class Heap { constructor() { this.heap = []; this.pushCount = Number.MIN_SAFE_INTEGER; } get length() { return this.heap.length; } empty () { this.heap = []; return this; } percUp(index) { let p; while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) { let t = this.heap[index]; this.heap[index] = this.heap[p]; this.heap[p] = t; index = p; } } percDown(index) { let l; while ((l=leftChi(index)) < this.heap.length) { if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) { l = l+1; } if (smaller(this.heap[index], this.heap[l])) { break; } let t = this.heap[index]; this.heap[index] = this.heap[l]; this.heap[l] = t; index = l; } } push(node) { node.pushCount = ++this.pushCount; this.heap.push(node); this.percUp(this.heap.length-1); } unshift(node) { return this.heap.push(node); } shift() { let [top] = this.heap; this.heap[0] = this.heap[this.heap.length-1]; this.heap.pop(); this.percDown(0); return top; } toArray() { return [...this]; } *[Symbol.iterator] () { for (let i = 0; i < this.heap.length; i++) { yield this.heap[i].data; } } remove (testFn) { let j = 0; for (let i = 0; i < this.heap.length; i++) { if (!testFn(this.heap[i])) { this.heap[j] = this.heap[i]; j++; } } this.heap.splice(j); for (let i = parent(this.heap.length-1); i >= 0; i--) { this.percDown(i); } return this; } } function leftChi(i) { return (i<<1)+1; } function parent(i) { return ((i+1)>>1)-1; } function smaller(x, y) { if (x.priority !== y.priority) { return x.priority < y.priority; } else { return x.pushCount < y.pushCount; } } /** * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and * completed in ascending priority order. * * @name priorityQueue * @static * @memberOf module:ControlFlow * @method * @see [async.queue]{@link module:ControlFlow.queue} * @category Control Flow * @param {AsyncFunction} worker - An async function for processing a queued task. * If you want to handle errors from an individual task, pass a callback to * `q.push()`. * Invoked with (task, callback). * @param {number} concurrency - An `integer` for determining how many `worker` * functions should be run in parallel. If omitted, the concurrency defaults to * `1`. If the concurrency is `0`, an error is thrown. * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two * differences between `queue` and `priorityQueue` objects: * * `push(task, priority, [callback])` - `priority` should be a number. If an * array of `tasks` is given, all tasks will be assigned the same priority. * * The `unshift` method was removed. */ function priorityQueue(worker, concurrency) { // Start with a normal queue var q = queue$1(worker, concurrency); q._tasks = new Heap(); // Override push to accept second parameter representing priority q.push = function(data, priority = 0, callback = () => {}) { if (typeof callback !== 'function') { throw new Error('task callback must be a function'); } q.started = true; if (!Array.isArray(data)) { data = [data]; } if (data.length === 0 && q.idle()) { // call drain immediately if there are no tasks return setImmediate$1(() => q.drain()); } for (var i = 0, l = data.length; i < l; i++) { var item = { data: data[i], priority, callback }; q._tasks.push(item); } setImmediate$1(q.process); }; // Remove unshift function delete q.unshift; return q; } /** * Runs the `tasks` array of functions in parallel, without waiting until the * previous function has completed. Once any of the `tasks` complete or pass an * error to its callback, the main `callback` is immediately called. It's * equivalent to `Promise.race()`. * * @name race * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} * to run. Each function can complete with an optional `result` value. * @param {Function} callback - A callback to run once any of the functions have * completed. This function gets an error or result from the first function that * completed. Invoked with (err, result). * @returns undefined * @example * * async.race([ * function(callback) { * setTimeout(function() { * callback(null, 'one'); * }, 200); * }, * function(callback) { * setTimeout(function() { * callback(null, 'two'); * }, 100); * } * ], * // main callback * function(err, result) { * // the result will be equal to 'two' as it finishes earlier * }); */ function race(tasks, callback) { callback = once(callback); if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); if (!tasks.length) return callback(); for (var i = 0, l = tasks.length; i < l; i++) { wrapAsync(tasks[i])(callback); } } var race$1 = awaitify(race, 2); /** * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. * * @name reduceRight * @static * @memberOf module:Collections * @method * @see [async.reduce]{@link module:Collections.reduce} * @alias foldr * @category Collection * @param {Array} array - A collection to iterate over. * @param {*} memo - The initial state of the reduction. * @param {AsyncFunction} iteratee - A function applied to each item in the * array to produce the next step in the reduction. * The `iteratee` should complete with the next state of the reduction. * If the iteratee complete with an error, the reduction is stopped and the * main `callback` is immediately called with the error. * Invoked with (memo, item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Result is the reduced value. Invoked with * (err, result). * @returns {Promise} a promise, if no callback is passed */ function reduceRight (array, memo, iteratee, callback) { var reversed = [...array].reverse(); return reduce$1(reversed, memo, iteratee, callback); } /** * Wraps the async function in another function that always completes with a * result object, even when it errors. * * The result object has either the property `error` or `value`. * * @name reflect * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} fn - The async function you want to wrap * @returns {Function} - A function that always passes null to it's callback as * the error. The second argument to the callback will be an `object` with * either an `error` or a `value` property. * @example * * async.parallel([ * async.reflect(function(callback) { * // do some stuff ... * callback(null, 'one'); * }), * async.reflect(function(callback) { * // do some more stuff but error ... * callback('bad stuff happened'); * }), * async.reflect(function(callback) { * // do some more stuff ... * callback(null, 'two'); * }) * ], * // optional callback * function(err, results) { * // values * // results[0].value = 'one' * // results[1].error = 'bad stuff happened' * // results[2].value = 'two' * }); */ function reflect(fn) { var _fn = wrapAsync(fn); return initialParams(function reflectOn(args, reflectCallback) { args.push((error, ...cbArgs) => { let retVal = {}; if (error) { retVal.error = error; } if (cbArgs.length > 0){ var value = cbArgs; if (cbArgs.length <= 1) { [value] = cbArgs; } retVal.value = value; } reflectCallback(null, retVal); }); return _fn.apply(this, args); }); } /** * A helper function that wraps an array or an object of functions with `reflect`. * * @name reflectAll * @static * @memberOf module:Utils * @method * @see [async.reflect]{@link module:Utils.reflect} * @category Util * @param {Array|Object|Iterable} tasks - The collection of * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. * @returns {Array} Returns an array of async functions, each wrapped in * `async.reflect` * @example * * let tasks = [ * function(callback) { * setTimeout(function() { * callback(null, 'one'); * }, 200); * }, * function(callback) { * // do some more stuff but error ... * callback(new Error('bad stuff happened')); * }, * function(callback) { * setTimeout(function() { * callback(null, 'two'); * }, 100); * } * ]; * * async.parallel(async.reflectAll(tasks), * // optional callback * function(err, results) { * // values * // results[0].value = 'one' * // results[1].error = Error('bad stuff happened') * // results[2].value = 'two' * }); * * // an example using an object instead of an array * let tasks = { * one: function(callback) { * setTimeout(function() { * callback(null, 'one'); * }, 200); * }, * two: function(callback) { * callback('two'); * }, * three: function(callback) { * setTimeout(function() { * callback(null, 'three'); * }, 100); * } * }; * * async.parallel(async.reflectAll(tasks), * // optional callback * function(err, results) { * // values * // results.one.value = 'one' * // results.two.error = 'two' * // results.three.value = 'three' * }); */ function reflectAll(tasks) { var results; if (Array.isArray(tasks)) { results = tasks.map(reflect); } else { results = {}; Object.keys(tasks).forEach(key => { results[key] = reflect.call(this, tasks[key]); }); } return results; } function reject(eachfn, arr, _iteratee, callback) { const iteratee = wrapAsync(_iteratee); return _filter(eachfn, arr, (value, cb) => { iteratee(value, (err, v) => { cb(err, !v); }); }, callback); } /** * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. * * @name reject * @static * @memberOf module:Collections * @method * @see [async.filter]{@link module:Collections.filter} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {Function} iteratee - An async truth test to apply to each item in * `coll`. * The should complete with a boolean value as its `result`. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed * @example * * async.reject(['file1','file2','file3'], function(filePath, callback) { * fs.access(filePath, function(err) { * callback(null, !err) * }); * }, function(err, results) { * // results now equals an array of missing files * createFiles(results); * }); */ function reject$1 (coll, iteratee, callback) { return reject(eachOf$1, coll, iteratee, callback) } var reject$2 = awaitify(reject$1, 3); /** * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a * time. * * @name rejectLimit * @static * @memberOf module:Collections * @method * @see [async.reject]{@link module:Collections.reject} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {Function} iteratee - An async truth test to apply to each item in * `coll`. * The should complete with a boolean value as its `result`. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed */ function rejectLimit (coll, limit, iteratee, callback) { return reject(eachOfLimit(limit), coll, iteratee, callback) } var rejectLimit$1 = awaitify(rejectLimit, 4); /** * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. * * @name rejectSeries * @static * @memberOf module:Collections * @method * @see [async.reject]{@link module:Collections.reject} * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {Function} iteratee - An async truth test to apply to each item in * `coll`. * The should complete with a boolean value as its `result`. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Invoked with (err, results). * @returns {Promise} a promise, if no callback is passed */ function rejectSeries (coll, iteratee, callback) { return reject(eachOfSeries$1, coll, iteratee, callback) } var rejectSeries$1 = awaitify(rejectSeries, 3); function constant$1(value) { return function () { return value; } } /** * Attempts to get a successful response from `task` no more than `times` times * before returning an error. If the task is successful, the `callback` will be * passed the result of the successful task. If all attempts fail, the callback * will be passed the error and result (if any) of the final attempt. * * @name retry * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @see [async.retryable]{@link module:ControlFlow.retryable} * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an * object with `times` and `interval` or a number. * * `times` - The number of attempts to make before giving up. The default * is `5`. * * `interval` - The time to wait between retries, in milliseconds. The * default is `0`. The interval may also be specified as a function of the * retry count (see example). * * `errorFilter` - An optional synchronous function that is invoked on * erroneous result. If it returns `true` the retry attempts will continue; * if the function returns `false` the retry flow is aborted with the current * attempt's error and result being returned to the final callback. * Invoked with (err). * * If `opts` is a number, the number specifies the number of times to retry, * with the default interval of `0`. * @param {AsyncFunction} task - An async function to retry. * Invoked with (callback). * @param {Function} [callback] - An optional callback which is called when the * task has succeeded, or after the final failed attempt. It receives the `err` * and `result` arguments of the last attempt at completing the `task`. Invoked * with (err, results). * @returns {Promise} a promise if no callback provided * * @example * * // The `retry` function can be used as a stand-alone control flow by passing * // a callback, as shown below: * * // try calling apiMethod 3 times * async.retry(3, apiMethod, function(err, result) { * // do something with the result * }); * * // try calling apiMethod 3 times, waiting 200 ms between each retry * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { * // do something with the result * }); * * // try calling apiMethod 10 times with exponential backoff * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) * async.retry({ * times: 10, * interval: function(retryCount) { * return 50 * Math.pow(2, retryCount); * } * }, apiMethod, function(err, result) { * // do something with the result * }); * * // try calling apiMethod the default 5 times no delay between each retry * async.retry(apiMethod, function(err, result) { * // do something with the result * }); * * // try calling apiMethod only when error condition satisfies, all other * // errors will abort the retry control flow and return to final callback * async.retry({ * errorFilter: function(err) { * return err.message === 'Temporary error'; // only retry on a specific error * } * }, apiMethod, function(err, result) { * // do something with the result * }); * * // to retry individual methods that are not as reliable within other * // control flow functions, use the `retryable` wrapper: * async.auto({ * users: api.getUsers.bind(api), * payments: async.retryable(3, api.getPayments.bind(api)) * }, function(err, results) { * // do something with the results * }); * */ const DEFAULT_TIMES = 5; const DEFAULT_INTERVAL = 0; function retry(opts, task, callback) { var options = { times: DEFAULT_TIMES, intervalFunc: constant$1(DEFAULT_INTERVAL) }; if (arguments.length < 3 && typeof opts === 'function') { callback = task || promiseCallback(); task = opts; } else { parseTimes(options, opts); callback = callback || promiseCallback(); } if (typeof task !== 'function') { throw new Error("Invalid arguments for async.retry"); } var _task = wrapAsync(task); var attempt = 1; function retryAttempt() { _task((err, ...args) => { if (err === false) return if (err && attempt++ < options.times && (typeof options.errorFilter != 'function' || options.errorFilter(err))) { setTimeout(retryAttempt, options.intervalFunc(attempt - 1)); } else { callback(err, ...args); } }); } retryAttempt(); return callback[PROMISE_SYMBOL] } function parseTimes(acc, t) { if (typeof t === 'object') { acc.times = +t.times || DEFAULT_TIMES; acc.intervalFunc = typeof t.interval === 'function' ? t.interval : constant$1(+t.interval || DEFAULT_INTERVAL); acc.errorFilter = t.errorFilter; } else if (typeof t === 'number' || typeof t === 'string') { acc.times = +t || DEFAULT_TIMES; } else { throw new Error("Invalid arguments for async.retry"); } } /** * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method * wraps a task and makes it retryable, rather than immediately calling it * with retries. * * @name retryable * @static * @memberOf module:ControlFlow * @method * @see [async.retry]{@link module:ControlFlow.retry} * @category Control Flow * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional * options, exactly the same as from `retry`, except for a `opts.arity` that * is the arity of the `task` function, defaulting to `task.length` * @param {AsyncFunction} task - the asynchronous function to wrap. * This function will be passed any arguments passed to the returned wrapper. * Invoked with (...args, callback). * @returns {AsyncFunction} The wrapped function, which when invoked, will * retry on an error, based on the parameters specified in `opts`. * This function will accept the same parameters as `task`. * @example * * async.auto({ * dep1: async.retryable(3, getFromFlakyService), * process: ["dep1", async.retryable(3, function (results, cb) { * maybeProcessData(results.dep1, cb); * })] * }, callback); */ function retryable (opts, task) { if (!task) { task = opts; opts = null; } let arity = (opts && opts.arity) || task.length; if (isAsync(task)) { arity += 1; } var _task = wrapAsync(task); return initialParams((args, callback) => { if (args.length < arity - 1 || callback == null) { args.push(callback); callback = promiseCallback(); } function taskFn(cb) { _task(...args, cb); } if (opts) retry(opts, taskFn, callback); else retry(taskFn, callback); return callback[PROMISE_SYMBOL] }); } /** * Run the functions in the `tasks` collection in series, each one running once * the previous function has completed. If any functions in the series pass an * error to its callback, no more functions are run, and `callback` is * immediately called with the value of the error. Otherwise, `callback` * receives an array of results when `tasks` have completed. * * It is also possible to use an object instead of an array. Each property will * be run as a function, and the results will be passed to the final `callback` * as an object instead of an array. This can be a more readable way of handling * results from {@link async.series}. * * **Note** that while many implementations preserve the order of object * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) * explicitly states that * * > The mechanics and order of enumerating the properties is not specified. * * So if you rely on the order in which your series of functions are executed, * and want this to work on all platforms, consider using an array. * * @name series * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing * [async functions]{@link AsyncFunction} to run in series. * Each function can complete with any number of optional `result` values. * @param {Function} [callback] - An optional callback to run once all the * functions have completed. This function gets a results array (or object) * containing all the result arguments passed to the `task` callbacks. Invoked * with (err, result). * @return {Promise} a promise, if no callback is passed * @example * async.series([ * function(callback) { * // do some stuff ... * callback(null, 'one'); * }, * function(callback) { * // do some more stuff ... * callback(null, 'two'); * } * ], * // optional callback * function(err, results) { * // results is now equal to ['one', 'two'] * }); * * async.series({ * one: function(callback) { * setTimeout(function() { * callback(null, 1); * }, 200); * }, * two: function(callback){ * setTimeout(function() { * callback(null, 2); * }, 100); * } * }, function(err, results) { * // results is now equal to: {one: 1, two: 2} * }); */ function series(tasks, callback) { return _parallel(eachOfSeries$1, tasks, callback); } /** * Returns `true` if at least one element in the `coll` satisfies an async test. * If any iteratee call returns `true`, the main `callback` is immediately * called. * * @name some * @static * @memberOf module:Collections * @method * @alias any * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collections in parallel. * The iteratee should complete with a boolean `result` value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the iteratee functions have finished. * Result will be either `true` or `false` depending on the values of the async * tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided * @example * * async.some(['file1','file2','file3'], function(filePath, callback) { * fs.access(filePath, function(err) { * callback(null, !err) * }); * }, function(err, result) { * // if result is true then at least one of the files exists * }); */ function some(coll, iteratee, callback) { return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback) } var some$1 = awaitify(some, 3); /** * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. * * @name someLimit * @static * @memberOf module:Collections * @method * @see [async.some]{@link module:Collections.some} * @alias anyLimit * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collections in parallel. * The iteratee should complete with a boolean `result` value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the iteratee functions have finished. * Result will be either `true` or `false` depending on the values of the async * tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided */ function someLimit(coll, limit, iteratee, callback) { return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback) } var someLimit$1 = awaitify(someLimit, 4); /** * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. * * @name someSeries * @static * @memberOf module:Collections * @method * @see [async.some]{@link module:Collections.some} * @alias anySeries * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async truth test to apply to each item * in the collections in series. * The iteratee should complete with a boolean `result` value. * Invoked with (item, callback). * @param {Function} [callback] - A callback which is called as soon as any * iteratee returns `true`, or after all the iteratee functions have finished. * Result will be either `true` or `false` depending on the values of the async * tests. Invoked with (err, result). * @returns {Promise} a promise, if no callback provided */ function someSeries(coll, iteratee, callback) { return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback) } var someSeries$1 = awaitify(someSeries, 3); /** * Sorts a list by the results of running each `coll` value through an async * `iteratee`. * * @name sortBy * @static * @memberOf module:Collections * @method * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {AsyncFunction} iteratee - An async function to apply to each item in * `coll`. * The iteratee should complete with a value to use as the sort criteria as * its `result`. * Invoked with (item, callback). * @param {Function} callback - A callback which is called after all the * `iteratee` functions have finished, or an error occurs. Results is the items * from the original `coll` sorted by the values returned by the `iteratee` * calls. Invoked with (err, results). * @returns {Promise} a promise, if no callback passed * @example * * async.sortBy(['file1','file2','file3'], function(file, callback) { * fs.stat(file, function(err, stats) { * callback(err, stats.mtime); * }); * }, function(err, results) { * // results is now the original array of files sorted by * // modified date * }); * * // By modifying the callback parameter the * // sorting order can be influenced: * * // ascending order * async.sortBy([1,9,3,5], function(x, callback) { * callback(null, x); * }, function(err,result) { * // result callback * }); * * // descending order * async.sortBy([1,9,3,5], function(x, callback) { * callback(null, x*-1); //<- x*-1 instead of x, turns the order around * }, function(err,result) { * // result callback * }); */ function sortBy (coll, iteratee, callback) { var _iteratee = wrapAsync(iteratee); return map$1(coll, (x, iterCb) => { _iteratee(x, (err, criteria) => { if (err) return iterCb(err); iterCb(err, {value: x, criteria}); }); }, (err, results) => { if (err) return callback(err); callback(null, results.sort(comparator).map(v => v.value)); }); function comparator(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; } } var sortBy$1 = awaitify(sortBy, 3); /** * Sets a time limit on an asynchronous function. If the function does not call * its callback within the specified milliseconds, it will be called with a * timeout error. The code property for the error object will be `'ETIMEDOUT'`. * * @name timeout * @static * @memberOf module:Utils * @method * @category Util * @param {AsyncFunction} asyncFn - The async function to limit in time. * @param {number} milliseconds - The specified time limit. * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) * to timeout Error for more information.. * @returns {AsyncFunction} Returns a wrapped function that can be used with any * of the control flow functions. * Invoke this function with the same parameters as you would `asyncFunc`. * @example * * function myFunction(foo, callback) { * doAsyncTask(foo, function(err, data) { * // handle errors * if (err) return callback(err); * * // do some stuff ... * * // return processed data * return callback(null, data); * }); * } * * var wrapped = async.timeout(myFunction, 1000); * * // call `wrapped` as you would `myFunction` * wrapped({ bar: 'bar' }, function(err, data) { * // if `myFunction` takes < 1000 ms to execute, `err` * // and `data` will have their expected values * * // else `err` will be an Error with the code 'ETIMEDOUT' * }); */ function timeout(asyncFn, milliseconds, info) { var fn = wrapAsync(asyncFn); return initialParams((args, callback) => { var timedOut = false; var timer; function timeoutCallback() { var name = asyncFn.name || 'anonymous'; var error = new Error('Callback function "' + name + '" timed out.'); error.code = 'ETIMEDOUT'; if (info) { error.info = info; } timedOut = true; callback(error); } args.push((...cbArgs) => { if (!timedOut) { callback(...cbArgs); clearTimeout(timer); } }); // setup timer and call original function timer = setTimeout(timeoutCallback, milliseconds); fn(...args); }); } function range(size) { var result = Array(size); while (size--) { result[size] = size; } return result; } /** * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a * time. * * @name timesLimit * @static * @memberOf module:ControlFlow * @method * @see [async.times]{@link module:ControlFlow.times} * @category Control Flow * @param {number} count - The number of times to run the function. * @param {number} limit - The maximum number of async operations at a time. * @param {AsyncFunction} iteratee - The async function to call `n` times. * Invoked with the iteration index and a callback: (n, next). * @param {Function} callback - see [async.map]{@link module:Collections.map}. * @returns {Promise} a promise, if no callback is provided */ function timesLimit(count, limit, iteratee, callback) { var _iteratee = wrapAsync(iteratee); return mapLimit$1(range(count), limit, _iteratee, callback); } /** * Calls the `iteratee` function `n` times, and accumulates results in the same * manner you would use with [map]{@link module:Collections.map}. * * @name times * @static * @memberOf module:ControlFlow * @method * @see [async.map]{@link module:Collections.map} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {AsyncFunction} iteratee - The async function to call `n` times. * Invoked with the iteration index and a callback: (n, next). * @param {Function} callback - see {@link module:Collections.map}. * @returns {Promise} a promise, if no callback is provided * @example * * // Pretend this is some complicated async factory * var createUser = function(id, callback) { * callback(null, { * id: 'user' + id * }); * }; * * // generate 5 users * async.times(5, function(n, next) { * createUser(n, function(err, user) { * next(err, user); * }); * }, function(err, users) { * // we should now have 5 users * }); */ function times (n, iteratee, callback) { return timesLimit(n, Infinity, iteratee, callback) } /** * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. * * @name timesSeries * @static * @memberOf module:ControlFlow * @method * @see [async.times]{@link module:ControlFlow.times} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {AsyncFunction} iteratee - The async function to call `n` times. * Invoked with the iteration index and a callback: (n, next). * @param {Function} callback - see {@link module:Collections.map}. * @returns {Promise} a promise, if no callback is provided */ function timesSeries (n, iteratee, callback) { return timesLimit(n, 1, iteratee, callback) } /** * A relative of `reduce`. Takes an Object or Array, and iterates over each * element in parallel, each step potentially mutating an `accumulator` value. * The type of the accumulator defaults to the type of collection passed in. * * @name transform * @static * @memberOf module:Collections * @method * @category Collection * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over. * @param {*} [accumulator] - The initial state of the transform. If omitted, * it will default to an empty Object or Array, depending on the type of `coll` * @param {AsyncFunction} iteratee - A function applied to each item in the * collection that potentially modifies the accumulator. * Invoked with (accumulator, item, key, callback). * @param {Function} [callback] - A callback which is called after all the * `iteratee` functions have finished. Result is the transformed accumulator. * Invoked with (err, result). * @returns {Promise} a promise, if no callback provided * @example * * async.transform([1,2,3], function(acc, item, index, callback) { * // pointless async: * process.nextTick(function() { * acc[index] = item * 2 * callback(null) * }); * }, function(err, result) { * // result is now equal to [2, 4, 6] * }); * * @example * * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) { * setImmediate(function () { * obj[key] = val * 2; * callback(); * }) * }, function (err, result) { * // result is equal to {a: 2, b: 4, c: 6} * }) */ function transform (coll, accumulator, iteratee, callback) { if (arguments.length <= 3 && typeof accumulator === 'function') { callback = iteratee; iteratee = accumulator; accumulator = Array.isArray(coll) ? [] : {}; } callback = once(callback || promiseCallback()); var _iteratee = wrapAsync(iteratee); eachOf$1(coll, (v, k, cb) => { _iteratee(accumulator, v, k, cb); }, err => callback(err, accumulator)); return callback[PROMISE_SYMBOL] } /** * It runs each task in series but stops whenever any of the functions were * successful. If one of the tasks were successful, the `callback` will be * passed the result of the successful task. If all tasks fail, the callback * will be passed the error and result (if any) of the final attempt. * * @name tryEach * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to * run, each function is passed a `callback(err, result)` it must call on * completion with an error `err` (which can be `null`) and an optional `result` * value. * @param {Function} [callback] - An optional callback which is called when one * of the tasks has succeeded, or all have failed. It receives the `err` and * `result` arguments of the last attempt at completing the `task`. Invoked with * (err, results). * @returns {Promise} a promise, if no callback is passed * @example * async.tryEach([ * function getDataFromFirstWebsite(callback) { * // Try getting the data from the first website * callback(err, data); * }, * function getDataFromSecondWebsite(callback) { * // First website failed, * // Try getting the data from the backup website * callback(err, data); * } * ], * // optional callback * function(err, results) { * Now do something with the data. * }); * */ function tryEach(tasks, callback) { var error = null; var result; return eachSeries$1(tasks, (task, taskCb) => { wrapAsync(task)((err, ...args) => { if (err === false) return taskCb(err); if (args.length < 2) { [result] = args; } else { result = args; } error = err; taskCb(err ? null : {}); }); }, () => callback(error, result)); } var tryEach$1 = awaitify(tryEach); /** * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, * unmemoized form. Handy for testing. * * @name unmemoize * @static * @memberOf module:Utils * @method * @see [async.memoize]{@link module:Utils.memoize} * @category Util * @param {AsyncFunction} fn - the memoized function * @returns {AsyncFunction} a function that calls the original unmemoized function */ function unmemoize(fn) { return (...args) => { return (fn.unmemoized || fn)(...args); }; } /** * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when * stopped, or an error occurs. * * @name whilst * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {AsyncFunction} test - asynchronous truth test to perform before each * execution of `iteratee`. Invoked with (). * @param {AsyncFunction} iteratee - An async function which is called each time * `test` passes. Invoked with (callback). * @param {Function} [callback] - A callback which is called after the test * function has failed and repeated execution of `iteratee` has stopped. `callback` * will be passed an error and any arguments passed to the final `iteratee`'s * callback. Invoked with (err, [results]); * @returns {Promise} a promise, if no callback is passed * @example * * var count = 0; * async.whilst( * function test(cb) { cb(null, count < 5); }, * function iter(callback) { * count++; * setTimeout(function() { * callback(null, count); * }, 1000); * }, * function (err, n) { * // 5 seconds have passed, n = 5 * } * ); */ function whilst(test, iteratee, callback) { callback = onlyOnce(callback); var _fn = wrapAsync(iteratee); var _test = wrapAsync(test); var results = []; function next(err, ...rest) { if (err) return callback(err); results = rest; if (err === false) return; _test(check); } function check(err, truth) { if (err) return callback(err); if (err === false) return; if (!truth) return callback(null, ...results); _fn(next); } return _test(check); } var whilst$1 = awaitify(whilst, 3); /** * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when * stopped, or an error occurs. `callback` will be passed an error and any * arguments passed to the final `iteratee`'s callback. * * The inverse of [whilst]{@link module:ControlFlow.whilst}. * * @name until * @static * @memberOf module:ControlFlow * @method * @see [async.whilst]{@link module:ControlFlow.whilst} * @category Control Flow * @param {AsyncFunction} test - asynchronous truth test to perform before each * execution of `iteratee`. Invoked with (callback). * @param {AsyncFunction} iteratee - An async function which is called each time * `test` fails. Invoked with (callback). * @param {Function} [callback] - A callback which is called after the test * function has passed and repeated execution of `iteratee` has stopped. `callback` * will be passed an error and any arguments passed to the final `iteratee`'s * callback. Invoked with (err, [results]); * @returns {Promise} a promise, if a callback is not passed * * @example * const results = [] * let finished = false * async.until(function test(page, cb) { * cb(null, finished) * }, function iter(next) { * fetchPage(url, (err, body) => { * if (err) return next(err) * results = results.concat(body.objects) * finished = !!body.next * next(err) * }) * }, function done (err) { * // all pages have been fetched * }) */ function until(test, iteratee, callback) { const _test = wrapAsync(test); return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback); } /** * Runs the `tasks` array of functions in series, each passing their results to * the next in the array. However, if any of the `tasks` pass an error to their * own callback, the next function is not executed, and the main `callback` is * immediately called with the error. * * @name waterfall * @static * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} * to run. * Each function should complete with any number of `result` values. * The `result` values will be passed as arguments, in order, to the next task. * @param {Function} [callback] - An optional callback to run once all the * functions have completed. This will be passed the results of the last task's * callback. Invoked with (err, [results]). * @returns undefined * @example * * async.waterfall([ * function(callback) { * callback(null, 'one', 'two'); * }, * function(arg1, arg2, callback) { * // arg1 now equals 'one' and arg2 now equals 'two' * callback(null, 'three'); * }, * function(arg1, callback) { * // arg1 now equals 'three' * callback(null, 'done'); * } * ], function (err, result) { * // result now equals 'done' * }); * * // Or, with named functions: * async.waterfall([ * myFirstFunction, * mySecondFunction, * myLastFunction, * ], function (err, result) { * // result now equals 'done' * }); * function myFirstFunction(callback) { * callback(null, 'one', 'two'); * } * function mySecondFunction(arg1, arg2, callback) { * // arg1 now equals 'one' and arg2 now equals 'two' * callback(null, 'three'); * } * function myLastFunction(arg1, callback) { * // arg1 now equals 'three' * callback(null, 'done'); * } */ function waterfall (tasks, callback) { callback = once(callback); if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); if (!tasks.length) return callback(); var taskIndex = 0; function nextTask(args) { var task = wrapAsync(tasks[taskIndex++]); task(...args, onlyOnce(next)); } function next(err, ...args) { if (err === false) return if (err || taskIndex === tasks.length) { return callback(err, ...args); } nextTask(args); } nextTask([]); } var waterfall$1 = awaitify(waterfall); /** * An "async function" in the context of Async is an asynchronous function with * a variable number of parameters, with the final parameter being a callback. * (`function (arg1, arg2, ..., callback) {}`) * The final callback is of the form `callback(err, results...)`, which must be * called once the function is completed. The callback should be called with a * Error as its first argument to signal that an error occurred. * Otherwise, if no error occurred, it should be called with `null` as the first * argument, and any additional `result` arguments that may apply, to signal * successful completion. * The callback must be called exactly once, ideally on a later tick of the * JavaScript event loop. * * This type of function is also referred to as a "Node-style async function", * or a "continuation passing-style function" (CPS). Most of the methods of this * library are themselves CPS/Node-style async functions, or functions that * return CPS/Node-style async functions. * * Wherever we accept a Node-style async function, we also directly accept an * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. * In this case, the `async` function will not be passed a final callback * argument, and any thrown error will be used as the `err` argument of the * implicit callback, and the return value will be used as the `result` value. * (i.e. a `rejected` of the returned Promise becomes the `err` callback * argument, and a `resolved` value becomes the `result`.) * * Note, due to JavaScript limitations, we can only detect native `async` * functions and not transpilied implementations. * Your environment must have `async`/`await` support for this to work. * (e.g. Node > v7.6, or a recent version of a modern browser). * If you are using `async` functions through a transpiler (e.g. Babel), you * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, * because the `async function` will be compiled to an ordinary function that * returns a promise. * * @typedef {Function} AsyncFunction * @static */ var index = { apply, applyEach: applyEach$1, applyEachSeries, asyncify, auto, autoInject, cargo, cargoQueue: cargo$1, compose, concat: concat$1, concatLimit: concatLimit$1, concatSeries: concatSeries$1, constant, detect: detect$1, detectLimit: detectLimit$1, detectSeries: detectSeries$1, dir, doUntil, doWhilst: doWhilst$1, each, eachLimit: eachLimit$2, eachOf: eachOf$1, eachOfLimit: eachOfLimit$2, eachOfSeries: eachOfSeries$1, eachSeries: eachSeries$1, ensureAsync, every: every$1, everyLimit: everyLimit$1, everySeries: everySeries$1, filter: filter$1, filterLimit: filterLimit$1, filterSeries: filterSeries$1, forever: forever$1, groupBy, groupByLimit: groupByLimit$1, groupBySeries, log, map: map$1, mapLimit: mapLimit$1, mapSeries: mapSeries$1, mapValues, mapValuesLimit: mapValuesLimit$1, mapValuesSeries, memoize, nextTick, parallel, parallelLimit, priorityQueue, queue: queue$1, race: race$1, reduce: reduce$1, reduceRight, reflect, reflectAll, reject: reject$2, rejectLimit: rejectLimit$1, rejectSeries: rejectSeries$1, retry, retryable, seq, series, setImmediate: setImmediate$1, some: some$1, someLimit: someLimit$1, someSeries: someSeries$1, sortBy: sortBy$1, timeout, times, timesLimit, timesSeries, transform, tryEach: tryEach$1, unmemoize, until, waterfall: waterfall$1, whilst: whilst$1, // aliases all: every$1, allLimit: everyLimit$1, allSeries: everySeries$1, any: some$1, anyLimit: someLimit$1, anySeries: someSeries$1, find: detect$1, findLimit: detectLimit$1, findSeries: detectSeries$1, flatMap: concat$1, flatMapLimit: concatLimit$1, flatMapSeries: concatSeries$1, forEach: each, forEachSeries: eachSeries$1, forEachLimit: eachLimit$2, forEachOf: eachOf$1, forEachOfSeries: eachOfSeries$1, forEachOfLimit: eachOfLimit$2, inject: reduce$1, foldl: reduce$1, foldr: reduceRight, select: filter$1, selectLimit: filterLimit$1, selectSeries: filterSeries$1, wrapSync: asyncify, during: whilst$1, doDuring: doWhilst$1 }; /* harmony default export */ __webpack_exports__["default"] = (index); /***/ }), /***/ "./node_modules/bail/index.js": /*!************************************!*\ !*** ./node_modules/bail/index.js ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = bail function bail(err) { if (err) { throw err } } /***/ }), /***/ "./node_modules/base64-js/index.js": /*!*****************************************!*\ !*** ./node_modules/base64-js/index.js ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.byteLength = byteLength exports.toByteArray = toByteArray exports.fromByteArray = fromByteArray var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (var i = 0, len = code.length; i < len; ++i) { lookup[i] = code[i] revLookup[code.charCodeAt(i)] = i } // Support decoding URL-safe base64 strings, as Node.js does. // See: https://en.wikipedia.org/wiki/Base64#URL_applications revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 function getLens (b64) { var len = b64.length if (len % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // Trim off extra bytes after placeholder bytes are found // See: https://github.com/beatgammit/base64-js/issues/42 var validLen = b64.indexOf('=') if (validLen === -1) validLen = len var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4) return [validLen, placeHoldersLen] } // base64 is 4/3 + up to two characters of the original data function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) var curByte = 0 // if there are placeholders, only get up to the last complete 4 chars var len = placeHoldersLen > 0 ? validLen - 4 : validLen var i for (i = 0; i < len; i += 4) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[curByte++] = (tmp >> 16) & 0xFF arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] parts.push( lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3F] + '==' ) } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + uint8[len - 1] parts.push( lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3F] + lookup[(tmp << 2) & 0x3F] + '=' ) } return parts.join('') } /***/ }), /***/ "./node_modules/canonicalize/lib/canonicalize.js": /*!*******************************************************!*\ !*** ./node_modules/canonicalize/lib/canonicalize.js ***! \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* jshint esversion: 6 */ /* jslint node: true */ module.exports = function serialize (object) { if (object === null || typeof object !== 'object' || object.toJSON != null) { return JSON.stringify(object); } if (Array.isArray(object)) { return '[' + object.reduce((t, cv, ci) => { const comma = ci === 0 ? '' : ','; const value = cv === undefined || typeof cv === 'symbol' ? null : cv; return t + comma + serialize(value); }, '') + ']'; } return '{' + Object.keys(object).sort().reduce((t, cv, ci) => { if (object[cv] === undefined || typeof object[cv] === 'symbol') { return t; } const comma = t.length === 0 ? '' : ','; return t + comma + serialize(cv) + ':' + serialize(object[cv]); }, '') + '}'; }; /***/ }), /***/ "./node_modules/chat-pane/lib/create.js": /*!**********************************************!*\ !*** ./node_modules/chat-pane/lib/create.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.findChat = findChat; exports.getChat = getChat; var _solidUi = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var _rdflib = __webpack_require__(/*! rdflib */ "./node_modules/rdflib/esm/index.js"); var _longChatPane = _interopRequireWildcard(__webpack_require__(/*! ./longChatPane */ "./node_modules/chat-pane/lib/longChatPane.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function getMe() { return _getMe.apply(this, arguments); } function _getMe() { _getMe = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() { var me; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: me = _solidUi.authn.currentUser(); if (!(me === null)) { _context.next = 3; break; } throw new Error('Current user not found! Not logged in?'); case 3: _context.next = 5; return _solidUi.store.fetcher.load(me.doc()); case 5: return _context.abrupt("return", me); case 6: case "end": return _context.stop(); } } }, _callee); })); return _getMe.apply(this, arguments); } function getPodRoot(_x) { return _getPodRoot.apply(this, arguments); } function _getPodRoot() { _getPodRoot = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(me) { var podRoot; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: podRoot = _solidUi.store.any(me, _solidUi.ns.space('storage'), undefined, me.doc()); if (podRoot) { _context2.next = 3; break; } throw new Error('Current user pod root not found!'); case 3: return _context2.abrupt("return", podRoot); case 4: case "end": return _context2.stop(); } } }, _callee2); })); return _getPodRoot.apply(this, arguments); } function sendInvite(_x2, _x3) { return _sendInvite.apply(this, arguments); } function _sendInvite() { _sendInvite = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(invitee, chatThing) { var inviteeInbox, inviteBody, inviteResponse, locationStr; return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return _solidUi.store.fetcher.load(invitee.doc()); case 2: inviteeInbox = _solidUi.store.any(invitee, _solidUi.ns.ldp('inbox'), undefined, invitee.doc()); if (inviteeInbox) { _context3.next = 5; break; } throw new Error("Invitee inbox not found! ".concat(invitee.value)); case 5: inviteBody = "\n<> a ;\n".concat(_solidUi.ns.rdf('seeAlso'), " <").concat(chatThing.value, "> . \n "); _context3.next = 8; return _solidUi.store.fetcher.webOperation('POST', inviteeInbox.value, { data: inviteBody, contentType: 'text/turtle' }); case 8: inviteResponse = _context3.sent; locationStr = inviteResponse.headers.get('location'); if (locationStr) { _context3.next = 12; break; } throw new Error("Invite sending returned a ".concat(inviteResponse.status)); case 12: case "end": return _context3.stop(); } } }, _callee3); })); return _sendInvite.apply(this, arguments); } function determineChatContainer(invitee, podRoot) { // Create chat // See https://gitter.im/solid/chat-app?at=5f3c800f855be416a23ae74a var chatContainerStr = new URL("IndividualChats/".concat(new URL(invitee.value).host, "/"), podRoot.value).toString(); return new _rdflib.NamedNode(chatContainerStr); } function createChatThing(_x4, _x5) { return _createChatThing.apply(this, arguments); } function _createChatThing() { _createChatThing = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(chatContainer, me) { var created; return regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return _longChatPane["default"].mintNew({ session: { store: _solidUi.store } }, { me: me, newBase: chatContainer.value }); case 2: created = _context4.sent; return _context4.abrupt("return", created.newInstance); case 4: case "end": return _context4.stop(); } } }, _callee4); })); return _createChatThing.apply(this, arguments); } function setAcl(_x6, _x7, _x8) { return _setAcl.apply(this, arguments); } function _setAcl() { _setAcl = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(chatContainer, me, invitee) { var chatAclDoc, aclBody, aclResponse; return regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: _context5.next = 2; return _solidUi.store.fetcher.load(chatContainer); case 2: // FIXME: check the Why value on this quad: chatAclDoc = _solidUi.store.any(chatContainer, new _rdflib.NamedNode('http://www.iana.org/assignments/link-relations/acl')); if (chatAclDoc) { _context5.next = 5; break; } throw new Error('Chat ACL doc not found!'); case 5: aclBody = "\n@prefix acl: .\n<#owner>\n a acl:Authorization;\n acl:agent <".concat(me.value, ">;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Write, acl:Control.\n<#invitee>\n a acl:Authorization;\n acl:agent <").concat(invitee.value, ">;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Append.\n"); _context5.next = 8; return _solidUi.store.fetcher.webOperation('PUT', chatAclDoc.value, { data: aclBody, contentType: 'text/turtle' }); case 8: aclResponse = _context5.sent; case 9: case "end": return _context5.stop(); } } }, _callee5); })); return _setAcl.apply(this, arguments); } function addToPrivateTypeIndex(_x9, _x10) { return _addToPrivateTypeIndex.apply(this, arguments); } function _addToPrivateTypeIndex() { _addToPrivateTypeIndex = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(chatThing, me) { var privateTypeIndex, reg, ins; return regeneratorRuntime.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: // Add to private type index privateTypeIndex = _solidUi.store.any(me, _solidUi.ns.solid('privateTypeIndex')); if (privateTypeIndex) { _context6.next = 3; break; } throw new Error('Private type index not found!'); case 3: _context6.next = 5; return _solidUi.store.fetcher.load(privateTypeIndex); case 5: reg = _solidUi.widgets.newThing(privateTypeIndex); ins = [(0, _rdflib.st)(reg, _solidUi.ns.rdf('type'), _solidUi.ns.solid('TypeRegistration'), privateTypeIndex.doc()), (0, _rdflib.st)(reg, _solidUi.ns.solid('forClass'), _solidUi.ns.meeting('LongChat'), privateTypeIndex.doc()), (0, _rdflib.st)(reg, _solidUi.ns.solid('instance'), chatThing, privateTypeIndex.doc())]; _context6.next = 9; return new Promise(function (resolve, reject) { _solidUi.store.updater.update([], ins, function (_uri, ok, errm) { if (!ok) { reject(new Error(errm)); } else { resolve(); } }); }); case 9: case "end": return _context6.stop(); } } }, _callee6); })); return _addToPrivateTypeIndex.apply(this, arguments); } function findChat(_x11) { return _findChat.apply(this, arguments); } function _findChat() { _findChat = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(invitee) { var me, podRoot, chatContainer, exists; return regeneratorRuntime.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: _context7.next = 2; return getMe(); case 2: me = _context7.sent; _context7.next = 5; return getPodRoot(me); case 5: podRoot = _context7.sent; chatContainer = determineChatContainer(invitee, podRoot); exists = true; _context7.prev = 8; _context7.next = 11; return _solidUi.store.fetcher.load(new _rdflib.NamedNode(chatContainer.value + _longChatPane.CHAT_LOCATION_IN_CONTAINER)); case 11: _context7.next = 16; break; case 13: _context7.prev = 13; _context7.t0 = _context7["catch"](8); exists = false; case 16: return _context7.abrupt("return", { me: me, chatContainer: chatContainer, exists: exists }); case 17: case "end": return _context7.stop(); } } }, _callee7, null, [[8, 13]]); })); return _findChat.apply(this, arguments); } function getChat(_x12) { return _getChat.apply(this, arguments); } function _getChat() { _getChat = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(invitee) { var createIfMissing, _yield$findChat, me, chatContainer, exists, chatThing, _args8 = arguments; return regeneratorRuntime.wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: createIfMissing = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : true; _context8.next = 3; return findChat(invitee); case 3: _yield$findChat = _context8.sent; me = _yield$findChat.me; chatContainer = _yield$findChat.chatContainer; exists = _yield$findChat.exists; if (!exists) { _context8.next = 9; break; } return _context8.abrupt("return", new _rdflib.NamedNode(chatContainer.value + _longChatPane.CHAT_LOCATION_IN_CONTAINER)); case 9: if (!createIfMissing) { _context8.next = 20; break; } _context8.next = 12; return createChatThing(chatContainer, me); case 12: chatThing = _context8.sent; _context8.next = 15; return sendInvite(invitee, chatThing); case 15: _context8.next = 17; return setAcl(chatContainer, me, invitee); case 17: _context8.next = 19; return addToPrivateTypeIndex(chatThing, me); case 19: return _context8.abrupt("return", chatThing); case 20: case "end": return _context8.stop(); } } }, _callee8); })); return _getChat.apply(this, arguments); } //# sourceMappingURL=create.js.map /***/ }), /***/ "./node_modules/chat-pane/lib/longChatPane.js": /*!****************************************************!*\ !*** ./node_modules/chat-pane/lib/longChatPane.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } /* Long Chat Pane ** ** A long chat consists a of a series of chat files saved by date. */ var UI = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var ns = UI.ns; var $rdf = __webpack_require__(/*! rdflib */ "./node_modules/rdflib/esm/index.js"); var mainClass = ns.meeting('LongChat'); // @@ something from SIOC? var CHAT_LOCATION_IN_CONTAINER = 'index.ttl#this'; // const menuIcon = 'noun_897914.svg' var SPANNER_ICON = 'noun_344563.svg'; // resize: horizontal; min-width: 20em; var SIDEBAR_COMPONENT_STYLE = UI.style.sidebarComponentStyle || ' padding: 0.5em; width: 100%;'; var SIDEBAR_STYLE = UI.style.sidebarStyle || 'overflow-x: auto; overflow-y: auto; border-radius: 1em; border: 0.1em solid white;'; // was purple border module.exports = { CHAT_LOCATION_IN_CONTAINER: CHAT_LOCATION_IN_CONTAINER, // noun_704.svg Canoe noun_346319.svg = 1 Chat noun_1689339.svg = three chat icon: UI.icons.iconBase + 'noun_1689339.svg', name: 'long chat', label: function label(subject, context) { var kb = context.session.store; if (kb.holds(subject, ns.rdf('type'), ns.meeting('LongChat'))) { // subject is the object return 'Chat channnel'; } // Looks like a message -- might not havre any class declared if (kb.any(subject, ns.sioc('content')) && kb.any(subject, ns.dct('created'))) { return 'message'; } return null; // Suppress pane otherwise }, mintClass: mainClass, mintNew: function mintNew(context, newPaneOptions) { var kb = context.session.store; var updater = kb.updater; if (newPaneOptions.me && !newPaneOptions.me.uri) { throw new Error('chat mintNew: Invalid userid ' + newPaneOptions.me); } var newInstance = newPaneOptions.newInstance = newPaneOptions.newInstance || kb.sym(newPaneOptions.newBase + CHAT_LOCATION_IN_CONTAINER); var newChatDoc = newInstance.doc(); kb.add(newInstance, ns.rdf('type'), ns.meeting('LongChat'), newChatDoc); kb.add(newInstance, ns.dc('title'), 'Chat channel', newChatDoc); kb.add(newInstance, ns.dc('created'), new Date(), newChatDoc); if (newPaneOptions.me) { kb.add(newInstance, ns.dc('author'), newPaneOptions.me, newChatDoc); } return new Promise(function (resolve, reject) { updater.put(newChatDoc, kb.statementsMatching(undefined, undefined, undefined, newChatDoc), 'text/turtle', function (uri2, ok, message) { if (ok) { resolve(newPaneOptions); } else { reject(new Error('FAILED to save new chat channel at: ' + uri2 + ' : ' + message)); } }); }); }, render: function render(subject, context, paneOptions) { var dom = context.dom; var kb = context.session.store; /* Preferences ** ** Things like whether to color text by author webid, to expand image URLs inline, ** expanded inline image height. ... ** In general, preferences can be set per user, per user/app combo, per instance, ** and per instance/user combo. Per instance? not sure about unless it is valuable ** for everyone to be seeing the same thing. */ // const DCT = $rdf.Namespace('http://purl.org/dc/terms/') var preferencesFormText = "\n\n @prefix rdf: .\n @prefix solid: .\n @prefix ui: .\n @prefix : <#>.\n\n :this\n \"Chat preferences\" ;\n a ui:Form ;\n ui:part :colorizeByAuthor, :expandImagesInline, :newestFirst, :inlineImageHeightEms;\n ui:parts ( :colorizeByAuthor :expandImagesInline :newestFirst :inlineImageHeightEms ).\n\n:colorizeByAuthor a ui:TristateField; ui:property solid:colorizeByAuthor;\n ui:label \"Color user input by user\".\n:expandImagesInline a ui:TristateField; ui:property solid:expandImagesInline;\n ui:label \"Expand image URLs inline\".\n:newestFirst a ui:TristateField; ui:property solid:newestFirst;\n ui:label \"Newest messages at the top\".\n\n:inlineImageHeightEms a ui:IntegerField; ui:property solid:inlineImageHeightEms;\n ui:label \"Inline image height (lines)\".\n\n"; var preferencesForm = kb.sym('https://solid.github.io/solid-panes/longCharPane/preferencesForm.ttl#this'); var preferencesFormDoc = preferencesForm.doc(); if (!kb.holds(undefined, undefined, undefined, preferencesFormDoc)) { // If not loaded already $rdf.parse(preferencesFormText, kb, preferencesFormDoc.uri, 'text/turtle'); // Load form directly } var preferenceProperties = kb.statementsMatching(null, ns.ui.property, null, preferencesFormDoc).map(function (st) { return st.object; }); // Preferences Menu // // Build a menu a the side (@@ reactive: on top?) function renderPreferencesSidebar(_x) { return _renderPreferencesSidebar.apply(this, arguments); } // @@ Split out into solid-ui function _renderPreferencesSidebar() { _renderPreferencesSidebar = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(context) { var dom, noun, preferencesArea, menuTable, registrationArea, statusArea, me; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: // const noun = 'chat room' dom = context.dom, noun = context.noun; preferencesArea = dom.createElement('div'); preferencesArea.appendChild(panelCloseButton(preferencesArea)); // @@ style below fix .. just make it onviious while testing preferencesArea.style = SIDEBAR_COMPONENT_STYLE; preferencesArea.style.minWidth = '25em'; // bit bigger preferencesArea.style.maxHeight = triptychHeight; menuTable = preferencesArea.appendChild(dom.createElement('table')); registrationArea = menuTable.appendChild(dom.createElement('tr')); statusArea = menuTable.appendChild(dom.createElement('tr')); me = UI.authn.currentUser(); if (!me) { _context.next = 15; break; } _context.next = 13; return UI.authn.registrationControl({ noun: noun, me: me, statusArea: statusArea, dom: dom, div: registrationArea }, chatChannel, mainClass); case 13: console.log('Registration control finsished.'); preferencesArea.appendChild(UI.preferences.renderPreferencesForm(chatChannel, mainClass, preferencesForm, { noun: noun, me: me, statusArea: statusArea, div: preferencesArea, dom: dom, kb: kb })); case 15: return _context.abrupt("return", preferencesArea); case 16: case "end": return _context.stop(); } } }, _callee); })); return _renderPreferencesSidebar.apply(this, arguments); } function panelCloseButton(panel) { function removePanel() { panel.parentNode.removeChild(panel); } var button = UI.widgets.button(context.dom, UI.icons.iconBase + 'noun_1180156.svg', 'close', removePanel); button.style["float"] = 'right'; button.style.margin = '0.7em'; delete button.style.backgroundColor; // do not want white return button; } function preferencesButtonPressed(_x2) { return _preferencesButtonPressed.apply(this, arguments); } // preferencesButtonPressed // All my chats // /* Build a other chats list drawer the side */ function _preferencesButtonPressed() { _preferencesButtonPressed = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_event) { return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (preferencesArea) { _context2.next = 4; break; } _context2.next = 3; return renderPreferencesSidebar({ dom: dom, noun: 'chat room' }); case 3: preferencesArea = _context2.sent; case 4: if (paneRight.contains(preferencesArea)) { // Close menu (hide or delete??) preferencesArea.parentNode.removeChild(preferencesArea); preferencesArea = null; } else { paneRight.appendChild(preferencesArea); } case 5: case "end": return _context2.stop(); } } }, _callee2); })); return _preferencesButtonPressed.apply(this, arguments); } function renderCreationControl(refreshTarget, noun) { var creationDiv = dom.createElement('div'); var me = UI.authn.currentUser(); var creationContext = { // folder: subject, div: creationDiv, dom: dom, noun: noun, statusArea: creationDiv, me: me, refreshTarget: refreshTarget }; var chatPane = context.session.paneRegistry.byName('chat'); var relevantPanes = [chatPane]; UI.create.newThingUI(creationContext, context, relevantPanes); // Have to pass panes down newUI return creationDiv; } function renderInstances(_x3, _x4) { return _renderInstances.apply(this, arguments); } function _renderInstances() { _renderInstances = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(theClass, noun) { var instancesDiv, context; return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: instancesDiv = dom.createElement('div'); context = { dom: dom, div: instancesDiv, noun: noun }; _context3.next = 4; return UI.authn.registrationList(context, { "public": true, "private": true, type: theClass }); case 4: instancesDiv.appendChild(renderCreationControl(instancesDiv, noun)); return _context3.abrupt("return", instancesDiv); case 6: case "end": return _context3.stop(); } } }, _callee3); })); return _renderInstances.apply(this, arguments); } var otherChatsArea = null; function otherChatsHandler(_x5) { return _otherChatsHandler.apply(this, arguments); } // otherChatsHandler // People in the chat // /* Build a participants list drawer the side */ function _otherChatsHandler() { _otherChatsHandler = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(_event) { return regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: if (otherChatsArea) { _context4.next = 10; break; } // Lazy build when needed // Expand otherChatsArea = dom.createElement('div'); otherChatsArea.style = SIDEBAR_COMPONENT_STYLE; otherChatsArea.style.maxHeight = triptychHeight; otherChatsArea.appendChild(panelCloseButton(otherChatsArea)); _context4.t0 = otherChatsArea; _context4.next = 8; return renderInstances(ns.meeting('LongChat'), 'chat'); case 8: _context4.t1 = _context4.sent; _context4.t0.appendChild.call(_context4.t0, _context4.t1); case 10: // Toggle visibility with button clicks if (paneLeft.contains(otherChatsArea)) { otherChatsArea.parentNode.removeChild(otherChatsArea); } else { paneLeft.appendChild(otherChatsArea); } case 11: case "end": return _context4.stop(); } } }, _callee4); })); return _otherChatsHandler.apply(this, arguments); } var participantsArea; function participantsHandler(_event) { if (!participantsArea) { // Expand participantsArea = dom.createElement('div'); participantsArea.style = SIDEBAR_COMPONENT_STYLE; participantsArea.style.maxHeight = triptychHeight; participantsArea.appendChild(panelCloseButton(participantsArea)); // Record my participation and display participants var me = UI.authn.currentUser(); if (!me) alert('Should be logeed in for partipants panel'); UI.pad.manageParticipation(dom, participantsArea, chatChannel.doc(), chatChannel, me, {}); } // Toggle appearance in sidebar with clicks // Note also it can remove itself using the X button if (paneLeft.contains(participantsArea)) { // Close participants (hide or delete??) participantsArea.parentNode.removeChild(participantsArea); participantsArea = null; } else { paneLeft.appendChild(participantsArea); } } // participantsHandler var chatChannel = subject; var selectedMessage = null; if (kb.holds(subject, ns.rdf('type'), ns.meeting('LongChat'))) { // subject is the chatChannel console.log('Chat channnel'); // Looks like a message -- might not havre any class declared } else if (kb.any(subject, ns.sioc('content')) && kb.any(subject, ns.dct('created'))) { console.log('message'); selectedMessage = subject; chatChannel = kb.any(null, ns.wf('message'), selectedMessage); if (!chatChannel) throw new Error('Message has no link to chatChannel'); } var div = dom.createElement('div'); // Three large columns for particpant, chat, Preferences. formula below just as a note // const windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight var triptychHeight = '20cm'; // @@ need to be able to set to window! var triptych = div.appendChild(dom.createElement('table')); triptych.style.maxHeight = '12"'; // Screen max var paneRow = triptych.appendChild(dom.createElement('tr')); var paneLeft = paneRow.appendChild(dom.createElement('td')); var paneMiddle = paneRow.appendChild(dom.createElement('td')); var paneRight = paneRow.appendChild(dom.createElement('td')); var paneBottom = triptych.appendChild(dom.createElement('tr')); paneLeft.style = SIDEBAR_STYLE; paneLeft.style.paddingRight = '1em'; paneRight.style = SIDEBAR_STYLE; paneRight.style.paddingLeft = '1em'; paneBottom.appendChild(dom.createElement('td')); var buttonCell = paneBottom.appendChild(dom.createElement('td')); paneBottom.appendChild(dom.createElement('td')); // Button to bring up participants drawer on left var participantsIcon = 'noun_339237.svg'; var participantsButton = UI.widgets.button(dom, UI.icons.iconBase + participantsIcon, 'participants ...'); // wider var buttonCell.appendChild(participantsButton); participantsButton.addEventListener('click', participantsHandler); // Button to bring up otherChats drawer on left var otherChatsIcon = 'noun_1689339.svg'; // long chat icon -- not ideal for a set of chats @@ var otherChatsButton = UI.widgets.button(dom, UI.icons.iconBase + otherChatsIcon, 'List of other chats ...'); // wider var buttonCell.appendChild(otherChatsButton); otherChatsButton.addEventListener('click', otherChatsHandler); var preferencesArea = null; var menuButton = UI.widgets.button(dom, UI.icons.iconBase + SPANNER_ICON, 'Setting ...'); // wider var buttonCell.appendChild(menuButton); menuButton.style["float"] = 'right'; menuButton.addEventListener('click', preferencesButtonPressed); div.setAttribute('class', 'chatPane'); var options = { infinite: true }; var participantsHandlerContext = { noun: 'chat room', div: div, dom: dom }; participantsHandlerContext.me = UI.authn.currentUser(); // If already logged on function buildPane() { return _buildPane.apply(this, arguments); } function _buildPane() { _buildPane = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() { var prefMap, propuri, chatControl; return regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: _context5.prev = 0; _context5.next = 3; return UI.preferences.getPreferencesForClass(chatChannel, mainClass, preferenceProperties, participantsHandlerContext); case 3: prefMap = _context5.sent; _context5.next = 9; break; case 6: _context5.prev = 6; _context5.t0 = _context5["catch"](0); UI.widgets.complain(participantsHandlerContext, _context5.t0); case 9: for (propuri in prefMap) { options[propuri.split('#')[1]] = prefMap[propuri]; } if (selectedMessage) { options.selectedMessage = selectedMessage; } if (paneOptions.solo) { // This is the top pane, title, scrollbar etc are ours options.solo = true; } _context5.next = 14; return UI.infiniteMessageArea(dom, kb, chatChannel, options); case 14: chatControl = _context5.sent; chatControl.style.resize = 'both'; chatControl.style.overflow = 'auto'; chatControl.style.maxHeight = triptychHeight; paneMiddle.appendChild(chatControl); case 19: case "end": return _context5.stop(); } } }, _callee5, null, [[0, 6]]); })); return _buildPane.apply(this, arguments); } buildPane().then(console.log('async - chat pane built')); return div; } }; //# sourceMappingURL=longChatPane.js.map /***/ }), /***/ "./node_modules/chat-pane/lib/main.js": /*!********************************************!*\ !*** ./node_modules/chat-pane/lib/main.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = { shortChatPane: __webpack_require__(/*! ./shortChatPane */ "./node_modules/chat-pane/lib/shortChatPane.js"), longChatPane: __webpack_require__(/*! ./longChatPane */ "./node_modules/chat-pane/lib/longChatPane.js"), getChat: __webpack_require__(/*! ./create */ "./node_modules/chat-pane/lib/create.js").getChat }; //# sourceMappingURL=main.js.map /***/ }), /***/ "./node_modules/chat-pane/lib/shortChatPane.js": /*!*****************************************************!*\ !*** ./node_modules/chat-pane/lib/shortChatPane.js ***! \*****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* Chat Pane ** ** Plan is to support a finte number of chat graph shapes ** and investigate the interop between them. */ /* global $rdf */ var UI = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); var ns = UI.ns; module.exports = { icon: UI.icons.iconBase + 'noun_346319.svg', name: 'chat', /* * As part of the work on merging the existing chat views (aka panes) into one view * https://github.com/solid/chat-pane/issues/17 * we want to dis-incentivize the use of Small Chat until we've gotten the work done * by making it difficult to create new data resources that uses the Small Chat view * but we still want existing resources to be viewed by the Small Chat view */ audience: [ns.solid('PowerUser')], /* AN RRSAgent IRC log: a foaf:ChatChannel foaf:chatEventList [ rdf:_100 <#T19-10-58> rdf:_101 <#T19-10-58-1> rdf:_102 .. <#T19-28-47-1> dc:creator [ a wn:Person; foaf:nick "timbl" ] dc:date "2016-03-15T19:28:47Z" dc:description "timbl has joined &mit" a foaf:chatEvent. */ label: function label(subject, context) { var kb = context.session.store; var n = kb.each(subject, ns.wf('message')).length; if (n > 0) return 'Chat (' + n + ')'; // Show how many in hover text if (kb.holds(subject, ns.rdf('type'), ns.meeting('Chat'))) { // subject is the file return 'Meeting chat'; } if (kb.holds(undefined, ns.rdf('type'), ns.foaf('ChatChannel'), subject)) { // subject is the file return 'IRC log'; // contains anything of this type } return null; // Suppress pane otherwise }, mintClass: ns.meeting('Chat'), mintNew: function mintNew(context, newPaneOptions) { var kb = context.session.store; var updater = kb.updater; if (newPaneOptions.me && !newPaneOptions.me.uri) { throw new Error('chat mintNew: Invalid userid ' + newPaneOptions.me); } var newInstance = newPaneOptions.newInstance = newPaneOptions.newInstance || kb.sym(newPaneOptions.newBase + 'index.ttl#this'); var newChatDoc = newInstance.doc(); kb.add(newInstance, ns.rdf('type'), ns.meeting('Chat'), newChatDoc); kb.add(newInstance, ns.dc('title'), 'Chat', newChatDoc); kb.add(newInstance, ns.dc('created'), new Date(), newChatDoc); if (newPaneOptions.me) { kb.add(newInstance, ns.dc('author'), newPaneOptions.me, newChatDoc); } return new Promise(function (resolve, reject) { updater.put(newChatDoc, kb.statementsMatching(undefined, undefined, undefined, newChatDoc), 'text/turtle', function (uri2, ok, message) { if (ok) { resolve(newPaneOptions); } else { reject(new Error('FAILED to save new tool at: ' + uri2 + ' : ' + message)); } }); }); }, render: function render(subject, context) { var kb = context.session.store; var dom = context.dom; var complain = function complain(message, color) { var pre = dom.createElement('pre'); pre.setAttribute('style', 'background-color: ' + color || false); div.appendChild(pre); pre.appendChild(dom.createTextNode(message)); }; var div = dom.createElement('div'); div.setAttribute('class', 'chatPane'); var options = {}; // Like newestFirst var messageStore; if (kb.holds(subject, ns.rdf('type'), ns.meeting('Chat'))) { // subject may be the file messageStore = subject.doc(); } else if (kb.any(subject, UI.ns.wf('message'))) { messageStore = UI.store.any(subject, UI.ns.wf('message')).doc(); } else if (kb.holds(undefined, ns.rdf('type'), ns.foaf('ChatChannel'), subject) || kb.holds(subject, ns.rdf('type'), ns.foaf('ChatChannel'))) { // subject is the file var ircLogQuery = function ircLogQuery() { var query = new $rdf.Query('IRC log entries'); var v = []; var vv = ['chan', 'msg', 'date', 'list', 'pred', 'creator', 'content']; vv.map(function (x) { query.vars.push(v[x] = $rdf.variable(x)); }); query.pat.add(v.chan, ns.foaf('chatEventList'), v.list); // chatEventList query.pat.add(v.list, v.pred, v.msg); // query.pat.add(v.msg, ns.dc('date'), v.date); query.pat.add(v.msg, ns.dc('creator'), v.creator); query.pat.add(v.msg, ns.dc('description'), v.content); return query; }; messageStore = subject.doc(); options.query = ircLogQuery(); } else { complain('Unknown chat type'); } // var context = {dom, div} // UI.authn.logIn(context).then( context => { // The widget itself sees to login div.appendChild(UI.messageArea(dom, kb, subject, messageStore, options)); kb.updater.addDownstreamChangeListener(messageStore, function () { UI.widgets.refreshTree(div); }); // Live update // }) return div; } }; //# sourceMappingURL=shortChatPane.js.map /***/ }), /***/ "./node_modules/contacts-pane/contactLogic.js": /*!****************************************************!*\ !*** ./node_modules/contacts-pane/contactLogic.js ***! \****************************************************/ /*! exports provided: updateMany, saveNewContact, sanitizeToAlpha, saveNewGroup, addPersonToGroup */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateMany", function() { return updateMany; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveNewContact", function() { return saveNewContact; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sanitizeToAlpha", function() { return sanitizeToAlpha; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveNewGroup", function() { return saveNewGroup; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addPersonToGroup", function() { return addPersonToGroup; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); // Logic for solid contacts const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const utils = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const updater = kb.updater /** Perform updates on more than one document @@ Move to rdflib! */ async function updateMany (deletions, insertions) { const docs = deletions.concat(insertions).map(st => st.why) const uniqueDocs = Array.from(new Set(docs)) const updates = uniqueDocs.map(doc => kb.updater.update(deletions.filter(st => st.why.sameTerm(doc)), insertions.filter(st => st.why.sameTerm(doc)))) return Promise.all(updates) } /** Add a new person to the web data * * adds them to the given groups as well. * @returns {NamedNode} the person */ async function saveNewContact (book, name, selectedGroups) { const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex')) const uuid = utils.genUuid() const person = kb.sym( book.dir().uri + 'Person/' + uuid + '/index.ttl#this' ) const doc = person.doc() // Set of statements to different files const agenda = [ // Patch the main index to add the person $rdf.st(person, ns.vcard('inAddressBook'), book, nameEmailIndex), // The people index $rdf.st(person, ns.vcard('fn'), name, nameEmailIndex), // The new person file $rdf.st(person, ns.vcard('fn'), name, doc), $rdf.st(person, ns.rdf('type'), ns.vcard('Individual'), doc), $rdf.st(doc, ns.dct('created'), new Date(), doc) // Note when created - useful for triaging later // Note this is propert of the file -- not when the person was created! ] for (const gu in selectedGroups) { const g = kb.sym(gu) const gd = g.doc() agenda.push( $rdf.st(g, ns.vcard('hasMember'), person, gd), $rdf.st(person, ns.vcard('fn'), name, gd) ) } try { await updateMany([], agenda) // @@ in future, updater.updateMany } catch (e) { console.log("Error: can't update " + person + ' as new contact:' + e) throw new Error('Updating new contact: ' + e) } return person } function sanitizeToAlpha (name) { // https://mathiasbynens.be/notes/es6-unicode-regex const n2 = name.replace(/\W/gu, '_') // Anything which is not a unicode word characeter return n2.replace(/_+/g, '_') // https://www.regular-expressions.info/shorthand.html } /** Write new group to web * Creates an empty new group file and adds it to the index * @returns group */ async function saveNewGroup (book, name) { const gix = kb.any(book, ns.vcard('groupIndex')) const gname = sanitizeToAlpha(name) const group = kb.sym(book.dir().uri + 'Group/' + gname + '.ttl#this') const doc = group.doc() console.log(' New group will be: ' + group + '\n') try { await kb.fetcher.load(gix) } catch (err) { throw new Error('Error loading group index!' + gix.uri + ': ' + err) } if (kb.holds(book, ns.vcard('includesGroup'), group, gix)) { return group // Already exists } const insertTriples = [ $rdf.st(book, ns.vcard('includesGroup'), group, gix), $rdf.st(group, ns.rdf('type'), ns.vcard('Group'), gix), $rdf.st(group, ns.vcard('fn'), name, gix) ] try { await updater.update([], insertTriples) } catch (e) { throw new Error('Could not update group index ' + e) // fail } const triples = [ $rdf.st(book, ns.vcard('includesGroup'), group, doc), // Pointer back to book $rdf.st(group, ns.rdf('type'), ns.vcard('Group'), doc), $rdf.st(group, ns.vcard('fn'), name, doc) ] try { await updater.update([], triples) } catch (err) { throw new Error('Could not update group file: ' + err) // fail } return group } async function addPersonToGroup (thing, group) { const toBeFetched = [thing.doc(), group.doc()] try { await kb.fetcher.load(toBeFetched) } catch (e) { throw new Error('addPersonToGroup: ' + e) } const types = kb.findTypeURIs(thing) for (const ty in types) { console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped? } if (!(ns.vcard('Individual').uri in types || ns.vcard('Organization').uri in types)) { return alert(`Can't add ${thing} to a group: it has to be an individual or another group.`) } const pname = kb.any(thing, ns.vcard('fn')) const gname = kb.any(group, ns.vcard('fn')) if (!pname) { return alert('No vcard name known for ' + thing) } const already = kb.holds(group, ns.vcard('hasMember'), thing, group.doc()) if (already) { return alert( 'ALREADY added ' + pname + ' to group ' + gname ) } const message = 'Add ' + pname + ' to group ' + gname + '?' if (!confirm(message)) return const ins = [ $rdf.st(group, ns.vcard('hasMember'), thing, group.doc()), $rdf.st(thing, ns.vcard('fn'), pname, group.doc()) ] try { await updater.update([], ins) } catch (e) { throw new Error(`Error adding ${pname} to group ${gname}:` + e) } return thing } /***/ }), /***/ "./node_modules/contacts-pane/contactsPane.js": /*!****************************************************!*\ !*** ./node_modules/contacts-pane/contactsPane.js ***! \****************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _toolsPane__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toolsPane */ "./node_modules/contacts-pane/toolsPane.js"); /* harmony import */ var _mintNewAddressBook__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mintNewAddressBook */ "./node_modules/contacts-pane/mintNewAddressBook.js"); /* harmony import */ var _individual__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./individual */ "./node_modules/contacts-pane/individual.js"); /* harmony import */ var _contactLogic__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./contactLogic */ "./node_modules/contacts-pane/contactLogic.js"); /* Contact AddressBook Pane ** ** This outline pane allows a user to interact with an contact, to change its state according to an ontology, comment on it, etc. ** ** See also things like ** http://www.w3.org/TR/vcard-rdf/ ** http://tools.ietf.org/html/rfc6350 ** http://www.iana.org/assignments/vcard-elements/vcard-elements.xhtml ** ** Feross "Standard" style note: Callback functions should not be called "callback" ** or the "standard" linter will complain if the first param is not a node.js error code. (2018-01) ** Hence "callbackFunction" */ /* global alert, confirm */ // const $rdf = UI.rdf const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const utils = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"] /* harmony default export */ __webpack_exports__["default"] = ({ icon: solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_99101.svg', // changed from embedded icon 2016-05-01 name: 'contact', // Does the subject deserve an contact pane? label: function (subject, context) { const t = context.session.store.findTypeURIs(subject) if (t[ns.vcard('Individual').uri]) return 'Contact' if (t[ns.vcard('Organization').uri]) return 'contact' if (t[ns.foaf('Person').uri]) return 'Person' if (t[ns.schema('Person').uri]) return 'Person' if (t[ns.vcard('Group').uri]) return 'Group' if (t[ns.vcard('AddressBook').uri]) return 'Address book' return null // No under other circumstances }, mintClass: solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].vcard('AddressBook'), mintNew: _mintNewAddressBook__WEBPACK_IMPORTED_MODULE_2__["mintNewAddressBook"], // Make a new address book // Render the pane render: function (subject, dataBrowserContext, paneOptions = {}) { const thisPane = this // stick functions here function complain (message) { console.log('contactsPane: ' + message) div.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message, 'pink')) } function complainIfBad (ok, body) { if (!ok) { complain('Error: ' + body) } } // Reproduction: Spawn a new instance of this app function newAddressBookButton (thisAddressBook) { return solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].newAppInstance( dom, { noun: 'address book', appPathSegment: 'contactorator.timbl.com' }, function (ws, newBase) { thisPane.clone(thisAddressBook, newBase, { // @@ clone is not a thing - use mintNew me: me, div: div, dom: dom }) } ) } // newAddressBookButton const dom = dataBrowserContext.dom const kb = dataBrowserContext.session.store const div = dom.createElement('div') const me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() // If already logged on solid_ui__WEBPACK_IMPORTED_MODULE_0__["aclControl"].preventBrowserDropEvents(dom) // protect drag and drop div.setAttribute('class', 'contactPane') asyncRender().then( () => console.log('contctsPane Rendered ' + subject), err => complain('' + err)) return div // Async part of render. Maybe API will later allow render to be async async function asyncRender () { const updater = kb.updater solid_ui__WEBPACK_IMPORTED_MODULE_0__["aclControl"].preventBrowserDropEvents(dom) const t = kb.findTypeURIs(subject) let me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() const context = { target: subject, me: me, noun: 'address book', div: div, dom: dom } // missing: statusRegion // Render a 3-column browser for an address book or a group function renderThreeColumnBrowser (books, context, options) { kb.fetcher .load(books) .then(function (_xhr) { renderThreeColumnBrowser2(books, context, options) }) .catch(function (err) { complain(err) }) } function renderThreeColumnBrowser2 (books, context, options) { const classLabel = utils.label(ns.vcard('AddressBook')) // const IndividualClassLabel = utils.label(ns.vcard('Individual')) let book = books[0] // for now const groupIndex = kb.any(book, ns.vcard('groupIndex')) let selectedGroups = {} let selectedPeople = {} // Actually prob max 1 const target = options.foreignGroup || book let title = kb.any(target, ns.dc('title')) || kb.any(target, ns.vcard('fn')) if (paneOptions.solo && title && typeof document !== 'undefined') { document.title = title.value // @@ only when the outermmost pane } title = title ? title.value : classLabel // The book could be the main subject, or linked from a group we are dealing with function findBookFromGroups (book) { if (book) { return book } let g for (const gu in selectedGroups) { g = kb.sym(gu) const b = kb.any(undefined, ns.vcard('includesGroup'), g) if (b) return b } throw new Error( 'findBookFromGroups: Cant find address book which this group is part of' ) } // Write a new contact to the web // organization-name is a hack for Mac records with no FN which is mandatory. function nameFor (x) { const name = kb.any(x, ns.vcard('fn')) || kb.any(x, ns.foaf('name')) || kb.any(x, ns.vcard('organization-name')) return name ? name.value : '???' } function filterName (name) { const filter = searchInput.value.trim().toLowerCase() if (filter.length === 0) return true const parts = filter.split(' ') // Each name part must be somewhere for (let j = 0; j < parts.length; j++) { const word = parts[j] if (name.toLowerCase().indexOf(word) < 0) return false } return true } function selectPerson (person) { cardMain.innerHTML = 'loading...' selectedPeople = {} selectedPeople[person.uri] = true refreshFilteredPeople() // Color to remember which one you picked const local = book ? localNode(person) : person kb.fetcher.nowOrWhenFetched(local.doc(), undefined, function ( ok, message ) { cardMain.innerHTML = '' if (!ok) { return complainIfBad( ok, "Can't load card: " + local + ': ' + message ) } // console.log("Loaded card " + local + '\n') cardMain.appendChild(renderPane(dom, local, 'contact')) cardMain.appendChild(dom.createElement('br')) cardMain.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].linkIcon(dom, local)) // hoverHide // Add in a delete button to delete from AB const deleteButton = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].deleteButtonWithCheck( dom, cardMain, 'contact', function () { const container = person.dir() // ASSUMPTION THAT CARD IS IN ITS OWN DIRECTORY // function warn (message) { return UI.widgets.errorMessageBlock(dom, message, 'straw') } alert('Conatiner to delete is ' + container) const pname = kb.any(person, ns.vcard('fn')) if ( confirm( 'Delete contact ' + pname + ' completely?? ' + container ) ) { console.log('Deleting a contact ' + pname) deleteThing(person) // - delete the references to it in group files and save them background // - delete the reference in people.ttl and save it back deleteRecursive(kb, container).then(_res => { refreshNames() // Doesn't work cardMain.innerHTML = 'Contact Data Deleted.' }) } } ) deleteButton.style = 'height: 2em;' }) } function refreshFilteredPeople (active) { let count = 0 let lastRow = null for (let i = 0; i < peopleMainTable.children.length; i++) { const row = peopleMainTable.children[i] const matches = filterName(nameFor(row.subject)) if (matches) { count++ lastRow = row } row.setAttribute( 'style', matches ? selectedPeople[row.subject.uri] ? 'background-color: #cce;' : '' : 'display: none;' ) } if (count === 1 && active) { const unique = lastRow.subject // selectedPeople = { } // selectedPeople[unique.uri] = true // lastRow.setAttribute('style', 'background-color: #cce;') selectPerson(unique) } } function selectAllGroups ( selectedGroups, groupsMainTable, callbackFunction ) { function fetchGroupAndSelct (group, groupRow) { groupRow.setAttribute('style', 'background-color: #ffe;') kb.fetcher.nowOrWhenFetched(group.doc(), undefined, function ( ok, message ) { if (!ok) { const msg = "Can't load group file: " + group + ': ' + message badness.push(msg) return complainIfBad(ok, msg) } groupRow.setAttribute('style', 'background-color: #cce;') selectedGroups[group.uri] = true refreshGroupsSelected() refreshNames() // @@ every time?? todo -= 1 if (!todo) { if (callbackFunction) { callbackFunction(badness.length === 0, badness) } } }) } let todo = groupsMainTable.children.length var badness = [] /* eslint-disable-line no-var */ for (let k = 0; k < groupsMainTable.children.length; k++) { const groupRow = groupsMainTable.children[k] const group = groupRow.subject fetchGroupAndSelct(group, groupRow) } // for each row } function groupsInOrder () { let sortMe = [] if (options.foreignGroup) { sortMe.push([ '', kb.any(options.foreignGroup, ns.vcard('fn')), options.foreignGroup ]) } if (book) { books.forEach(function (book) { const gs = book ? kb.each(book, ns.vcard('includesGroup'), null, groupIndex) : [] const gs2 = gs.map(function (g) { return [book, kb.any(g, ns.vcard('fn')), g] }) sortMe = sortMe.concat(gs2) }) sortMe.sort() } return sortMe.map(tuple => tuple[2]) } function renderPane (dom, subject, paneName) { const p = dataBrowserContext.session.paneRegistry.byName(paneName) const d = p.render(subject, dataBrowserContext) d.setAttribute( 'style', 'border: 0.1em solid #444; border-radius: 0.5em' ) return d } function compareForSort (self, other) { let s = nameFor(self) let o = nameFor(other) if (s && o) { s = s.toLowerCase() o = o.toLowerCase() if (s > o) return 1 if (s < o) return -1 } if (self.uri > other.uri) return 1 if (self.uri < other.uri) return -1 return 0 } // In a LDP work, deletes the whole document describing a thing // plus patch out ALL mentiosn of it! Use with care! // beware of other dta picked up from other places being smushed // together and then deleted. function deleteThing (x) { console.log('deleteThing: ' + x) const ds = kb .statementsMatching(x) .concat(kb.statementsMatching(undefined, undefined, x)) const targets = {} ds.forEach(function (st) { targets[st.why.uri] = st }) const agenda = [] // sets of statements of same document to delete for (const target in targets) { agenda.push( ds.filter(function (st) { return st.why.uri === target }) ) console.log( ' Deleting ' + agenda[agenda.length - 1].length + ' triples from ' + target ) } function nextOne () { if (agenda.length > 0) { updater.update(agenda.shift(), [], function (uri, ok, body) { if (!ok) { complain('Error deleting all trace of: ' + x + ': ' + body) return } nextOne() }) } else { console.log('Deleting resoure ' + x.doc()) kb.fetcher .delete(x.doc()) .then(function () { console.log('Delete thing ' + x + ': complete.') }) .catch(function (e) { complain('Error deleting thing ' + x + ': ' + e) }) } } nextOne() } // For deleting an addressbook sub-folder eg person - use with care! // @@ move to solid-logic function deleteRecursive (kb, folder) { return new Promise(function (resolve) { kb.fetcher.load(folder).then(function () { const promises = kb.each(folder, ns.ldp('contains')).map(file => { if (kb.holds(file, ns.rdf('type'), ns.ldp('BasicContainer'))) { return deleteRecursive(kb, file) } else { console.log('deleteRecirsive file: ' + file) if (!confirm(' Really DELETE File ' + file)) { throw new Error('User aborted delete file') } return kb.fetcher.webOperation('DELETE', file.uri) } }) console.log('deleteRecirsive folder: ' + folder) if (!confirm(' Really DELETE folder ' + folder)) { throw new Error('User aborted delete file') } promises.push(kb.fetcher.webOperation('DELETE', folder.uri)) Promise.all(promises).then(_res => { resolve() }) }) }) } function localNode (person, _div) { const aliases = kb.allAliases(person) const prefix = book.dir().uri for (let i = 0; i < aliases.length; i++) { if (aliases[i].uri.slice(0, prefix.length) === prefix) { return aliases[i] } } throw new Error('No local URI for ' + person) } /** Refresh the list of names */ function refreshNames () { function setPersonListener (personRow, person) { personRow.addEventListener('click', function (event) { event.preventDefault() selectPerson(person) }) } let cards = [] for (const u in selectedGroups) { if (selectedGroups[u]) { const a = kb.each(kb.sym(u), ns.vcard('hasMember')) cards = cards.concat(a) } } cards.sort(compareForSort) // @@ sort by name not UID later for (let k = 0; k < cards.length - 1;) { if (cards[k].uri === cards[k + 1].uri) { cards.splice(k, 1) // Eliminate duplicates from more than one group } else { k++ } } peopleHeader.textContent = cards.length > 5 ? '' + cards.length + ' contacts' : 'contact' function renderNameInGroupList (person) { const personRow = dom.createElement('tr') const personLeft = personRow.appendChild(dom.createElement('td')) // const personRight = personRow.appendChild(dom.createElement('td')) personLeft.setAttribute('style', dataCellStyle) personRow.subject = person const name = nameFor(person) personLeft.textContent = name personRow.subject = person solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDraggable(personRow, person) setPersonListener(personRow, person) return personRow } utils.syncTableToArrayReOrdered(peopleMainTable, cards, renderNameInGroupList) refreshFilteredPeople() } // refreshNames function refreshThingsSelected (table, selectionArray) { for (let i = 0; i < table.children.length; i++) { const row = table.children[i] if (row.subject) { row.setAttribute( 'style', selectionArray[row.subject.uri] ? 'background-color: #cce;' : '' ) } } } function refreshGroupsSelected () { return refreshThingsSelected(groupsMainTable, selectedGroups) } // Check every group is in the list and add it if not. function syncGroupTable () { function renderGroupRow (group) { // Is something is dropped on a group, add people to group async function handleURIsDroppedOnGroup (uris) { uris.forEach(function (u) { console.log('Dropped on group: ' + u) const thing = kb.sym(u) try { Object(_contactLogic__WEBPACK_IMPORTED_MODULE_4__["addPersonToGroup"])(thing, group) } catch (e) { complain(e) } refreshNames() }) } function groupRowClickListener (event) { event.preventDefault() const groupList = kb.sym(group.uri.split('#')[0]) if (!event.metaKey) { selectedGroups = {} // If Command key pressed, accumulate multiple } selectedGroups[group.uri] = !selectedGroups[group.uri] refreshGroupsSelected() peopleMainTable.innerHTML = '' // clear in case refreshNames doesn't work for unknown reason kb.fetcher.nowOrWhenFetched( groupList.uri, undefined, function (ok, message) { if (!ok) { return complainIfBad( ok, "Can't load group file: " + groupList + ': ' + message ) } refreshNames() if (!event.metaKey) { // If only one group has been selected, show ACL cardMain.innerHTML = '' let visible = false const aclControl = solid_ui__WEBPACK_IMPORTED_MODULE_0__["aclControl"].ACLControlBox5( group, dataBrowserContext, 'group', kb, function (ok, body, response) { if (!ok) { if (response && response.status && response.status === 403) { cardMain.innerHTML = 'No control access.' } else { cardMain.innerHTML = 'Failed to load access control: ' + body } } } ) const sharingButton = cardMain.appendChild( dom.createElement('button') ) sharingButton.style.cssText = 'padding: 1em; margin: 1em' const img = sharingButton.appendChild( dom.createElement('img') ) img.style.cssText = 'width: 1.5em; height: 1.5em' img.setAttribute( 'src', solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_123691.svg' ) sharingButton.addEventListener('click', function () { visible = !visible if (visible) { cardMain.appendChild(aclControl) } else { cardMain.removeChild(aclControl) } }) } } ) } // Body of renderGroupRow const name = kb.any(group, ns.vcard('fn')) const groupRow = dom.createElement('tr') groupRow.subject = group solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDraggable(groupRow, group) groupRow.setAttribute('style', dataCellStyle) groupRow.textContent = name solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDropTarget(groupRow, handleURIsDroppedOnGroup) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].deleteButtonWithCheck( dom, groupRow, 'group ' + name, function () { deleteThing(group) syncGroupTable() } ) groupRow.addEventListener('click', groupRowClickListener, true) return groupRow } // renderGroupRow const groups = groupsInOrder() utils.syncTableToArrayReOrdered(groupsMainTable, groups, renderGroupRow) refreshGroupsSelected() } // syncGroupTable // Click on New Group button async function newGroupClickHandler (_event) { cardMain.innerHTML = '' const groupIndex = kb.any(book, ns.vcard('groupIndex')) try { await fetch.load(groupIndex) } catch (e) { console.log('Error: Group index NOT loaded:' + e + '\n') } console.log(' Group index has been loaded\n') const name = await solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].askName( dom, kb, cardMain, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].foaf('name'), ns.vcard('Group'), 'group') if (!name) return // cancelled by user let group try { group = await Object(_contactLogic__WEBPACK_IMPORTED_MODULE_4__["saveNewGroup"])(book, name) } catch (err) { console.log("Error: can't save new group:" + err) cardMain.innerHTML = 'Failed to save group' + err return } selectedGroups = {} selectedGroups[group.uri] = true syncGroupTable() // Refresh list of groups cardMain.innerHTML = '' cardMain.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["aclControl"].ACLControlBox5( group.doc(), dataBrowserContext, 'group', kb, function (ok, body) { if (!ok) { cardMain.innerHTML = 'Group sharing setup failed: ' + body } })) } // newGroupClickHandler async function newContactClickHandler (_event) { cardMain.innerHTML = '' const ourBook = findBookFromGroups(book) try { await kb.fetcher.load(ourBook) } catch (err) { throw new Error("Book won't load:" + ourBook) } const nameEmailIndex = kb.any(ourBook, ns.vcard('nameEmailIndex')) if (!nameEmailIndex) throw new Error('Wot no nameEmailIndex?') await kb.fetcher.load(nameEmailIndex) console.log('Name index loaded async' + nameEmailIndex) const name = await solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"] .askName(dom, kb, cardMain, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].foaf('name'), ns.vcard('Individual'), 'person') if (!name) return // cancelled by user cardMain.innerHTML = 'indexing...' book = findBookFromGroups(book) let person try { person = await Object(_contactLogic__WEBPACK_IMPORTED_MODULE_4__["saveNewContact"])(book, name, selectedGroups) } catch (err) { const msg = "Error: can't save new contact: " + err console.log(msg) alert(msg) } selectedPeople = {} selectedPeople[person.uri] = true refreshNames() // Add name to list of group cardMain.innerHTML = '' // Clear 'indexing' cardMain.appendChild(renderPane(dom, person, 'contact')) } // //////////////////////////// Three-column Contact Browser - Body // ////////////////// Body of 3-column browser const bookTable = dom.createElement('table') bookTable.setAttribute( 'style', 'border-collapse: collapse; margin-right: 0; max-height: 9in;' ) div.appendChild(bookTable) /* bookTable.innerHTML = ` ` */ const bookHeader = bookTable.appendChild(dom.createElement('tr')) const bookMain = bookTable.appendChild(dom.createElement('tr')) const bookFooter = bookTable.appendChild(dom.createElement('tr')) const groupsHeader = bookHeader.appendChild(dom.createElement('td')) const peopleHeader = bookHeader.appendChild(dom.createElement('td')) const cardHeader = bookHeader.appendChild(dom.createElement('td')) const groupsMain = bookMain.appendChild(dom.createElement('td')) const groupsMainTable = groupsMain.appendChild(dom.createElement('table')) const peopleMain = bookMain.appendChild(dom.createElement('td')) const peopleMainTable = peopleMain.appendChild(dom.createElement('table')) const groupsFooter = bookFooter.appendChild(dom.createElement('td')) const peopleFooter = bookFooter.appendChild(dom.createElement('td')) const cardFooter = bookFooter.appendChild(dom.createElement('td')) cardHeader.appendChild(dom.createElement('div')) // searchDiv // searchDiv.setAttribute('style', 'border: 0.1em solid #888; border-radius: 0.5em') const searchInput = cardHeader.appendChild(dom.createElement('input')) searchInput.setAttribute('type', 'text') searchInput.setAttribute( 'style', 'border: 0.1em solid #444; border-radius: 0.5em; width: 100%; font-size: 100%; padding: 0.1em 0.6em' ) searchInput.addEventListener('input', function (_event) { refreshFilteredPeople(true) // Active: select person if just one left }) const cardMain = bookMain.appendChild(dom.createElement('td')) cardMain.setAttribute('style', 'margin: 0;') // fill space available const dataCellStyle = 'padding: 0.1em;' groupsHeader.textContent = 'groups' groupsHeader.setAttribute( 'style', 'min-width: 10em; padding-bottom 0.2em;' ) function setGroupListVisibility (visible) { const vis = visible ? '' : 'display: none;' groupsHeader.setAttribute( 'style', 'min-width: 10em; padding-bottom 0.2em;' + vis ) const hfstyle = 'padding: 0.1em;' groupsMain.setAttribute('style', hfstyle + vis) groupsFooter.setAttribute('style', hfstyle + vis) } setGroupListVisibility(true) if (options.foreignGroup) { selectedGroups[options.foreignGroup.uri] = true } if (book) { const allGroups = groupsHeader.appendChild(dom.createElement('button')) allGroups.textContent = 'All' const style = 'margin-left: 1em; font-size: 100%;' allGroups.setAttribute('style', style) allGroups.addEventListener('click', function (_event) { allGroups.state = allGroups.state ? 0 : 1 peopleMainTable.innerHTML = '' // clear in case refreshNames doesn't work for unknown reason if (allGroups.state) { allGroups.setAttribute('style', style + 'background-color: #ff8;') selectAllGroups(selectedGroups, groupsMainTable, function ( ok, message ) { if (!ok) return complain(message) allGroups.setAttribute( 'style', style + 'background-color: black; color: white' ) refreshGroupsSelected() }) } else { allGroups.setAttribute('style', style + 'background-color: #cfc;') // pale green hint groups loaded selectedGroups = {} refreshGroupsSelected() } }) // on button click kb.fetcher.nowOrWhenFetched(groupIndex.uri, book, function (ok, body) { if (!ok) return console.log('Cannot load group index: ' + body) syncGroupTable() refreshNames() }) } else { syncGroupTable() refreshNames() console.log('No book, only one group -> hide list of groups') setGroupListVisibility(false) // If no books involved, hide group list } // if not book peopleHeader.textContent = 'name' peopleHeader.setAttribute('style', 'min-width: 18em;') peopleMain.setAttribute('style', 'overflow:scroll;') // New Contact button const newContactButton = dom.createElement('button') const container = dom.createElement('div') newContactButton.setAttribute('type', 'button') if (!me) newContactButton.setAttribute('disabled', 'true') solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].checkUser().then(webId => { if (webId) { me = webId newContactButton.removeAttribute('disabled') } }) container.appendChild(newContactButton) newContactButton.innerHTML = 'New Contact' // + IndividualClassLabel peopleFooter.appendChild(container) newContactButton.addEventListener('click', newContactClickHandler, false) // New Group button if (book) { const newGroupButton = groupsFooter.appendChild( dom.createElement('button') ) newGroupButton.setAttribute('type', 'button') newGroupButton.innerHTML = 'New Group' // + IndividualClassLabel newGroupButton.addEventListener( 'click', newGroupClickHandler, false ) // Tools button const toolsButton = cardFooter.appendChild(dom.createElement('button')) toolsButton.setAttribute('type', 'button') toolsButton.innerHTML = 'Tools' toolsButton.addEventListener('click', function (_event) { cardMain.innerHTML = '' cardMain.appendChild( Object(_toolsPane__WEBPACK_IMPORTED_MODULE_1__["toolsPane"])( selectAllGroups, selectedGroups, groupsMainTable, book, dataBrowserContext, me ) ) }) } // if book cardFooter.appendChild(newAddressBookButton(book)) // }) div.appendChild(dom.createElement('hr')) // div.appendChild(newAddressBookButton(book)) // later // end of AddressBook instance } // renderThreeColumnBrowser // /////////////////////////////////////////////////////////////////////////////////// // Render a single contact Individual if ( t[ns.vcard('Individual').uri] || t[ns.vcard('Organization').uri] || t[ns.foaf('Person').uri] || t[ns.schema('Person').uri] ) { Object(_individual__WEBPACK_IMPORTED_MODULE_3__["renderIndividual"])(dom, div, subject, dataBrowserContext).then(() => console.log('(individual rendered)')) // Render a Group instance } else if (t[ns.vcard('Group').uri]) { // If we have a main address book, then render this group as a guest group within it solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"] .findAppInstances(context, ns.vcard('AddressBook')) .then(function (context) { const addressBooks = context.instances const options = { foreignGroup: subject } if (addressBooks.length > 0) { // const book = addressBooks[0] renderThreeColumnBrowser(addressBooks, context, options) } else { renderThreeColumnBrowser([], context, options) // @@ button to Make a new addressBook } }) .catch(function (e) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].complain(context, e) }) // Render a AddressBook instance } else if (t[ns.vcard('AddressBook').uri]) { renderThreeColumnBrowser([subject], context, {}) } else { console.log( 'Error: Contact pane: No evidence that ' + subject + ' is anything to do with contacts.' ) } me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() if (!me) { console.log( '(You do not have your Web Id set. Sign in or sign up to make changes.)' ) solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].logInLoadProfile(context).then( context => { console.log('Logged in as ' + context.me) me = context.me }, err => { div.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(err)) } ) } else { // console.log("(Your webid is "+ me +")") } // /////////////// Fix user when testing on a plane if ( typeof document !== 'undefined' && document.location && ('' + document.location).slice(0, 16) === 'http://localhost' ) { me = kb.any(subject, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].acl('owner')) // when testing on plane with no webid console.log('Assuming user is ' + me) } return div } // asyncRender } // render function }); // pane object // ends /***/ }), /***/ "./node_modules/contacts-pane/groupMembershipControl.js": /*!**************************************************************!*\ !*** ./node_modules/contacts-pane/groupMembershipControl.js ***! \**************************************************************/ /*! exports provided: renderGroupMemberships */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderGroupMemberships", function() { return renderGroupMemberships; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); // Render a control to record the group memberships we have for this agent const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] // const buttons = UI.buttonsn no // const widgets = UI.widgets const utils = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] // const style = UI.style // Groups the person is a member of async function renderGroupMemberships (person, context) { // Remove a person from a group function removeFromGroup (thing, group) { const pname = kb.any(thing, ns.vcard('fn')) const gname = kb.any(group, ns.vcard('fn')) const groups = kb.each(null, ns.vcard('hasMember'), thing) if (groups.length < 2) { alert( 'Must be a member of at least one group. Add to another group first.' ) return } const message = 'Remove ' + pname + ' from group ' + gname + '?' if (confirm(message)) { const del = [ $rdf.st(group, ns.vcard('hasMember'), thing, group.doc()), $rdf.st(thing, ns.vcard('fn'), pname, group.doc()) ] kb.updater.update(del, [], function (uri, ok, err) { if (!ok) { const message = 'Error removing member from group ' + group + ': ' + err groupList.parentNode.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message, 'pink')) return } console.log('Removed ' + pname + ' from group ' + gname) syncGroupList() }) } } function newRowForGroup (group) { const options = { deleteFunction: function () { removeFromGroup(person, group) }, noun: 'membership' } const tr = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].personTR(dom, null, group, options) return tr } function syncGroupList () { const groups = kb.each(null, ns.vcard('hasMember'), person) utils.syncTableToArray(groupList, groups, newRowForGroup) } const { dom } = context const groupList = dom.createElement('table') groupList.refresh = syncGroupList syncGroupList() return groupList } /***/ }), /***/ "./node_modules/contacts-pane/individual.js": /*!**************************************************!*\ !*** ./node_modules/contacts-pane/individual.js ***! \**************************************************/ /*! exports provided: renderIndividual */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderIndividual", function() { return renderIndividual; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _mugshotGallery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mugshotGallery */ "./node_modules/contacts-pane/mugshotGallery.js"); /* harmony import */ var _webidControl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webidControl */ "./node_modules/contacts-pane/webidControl.js"); /* harmony import */ var _groupMembershipControl_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./groupMembershipControl.js */ "./node_modules/contacts-pane/groupMembershipControl.js"); /* harmony import */ var _individualForm__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./individualForm */ "./node_modules/contacts-pane/individualForm.js"); /* harmony import */ var _individualForm__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_individualForm__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var _vcard_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./vcard.js */ "./node_modules/contacts-pane/vcard.js"); const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] // const utils = UI.utils const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] // Render Individual card async function renderIndividual (dom, div, subject, dataBrowserContext) { // //////////////////// DRAG and Drop for mugshot image function complain (message) { console.log(message) div.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message, 'pink')) } function spacer () { div .appendChild(dom.createElement('div')) .setAttribute('style', 'height: 1em') } function complainIfBad (ok, body) { if (!ok) { complain('Error: ' + body) } } function setPaneStyle () { const types = kb.findTypeURIs(subject) let mystyle = 'padding: 0.5em 1.5em 1em 1.5em; ' let backgroundColor = null for (const uri in types) { backgroundColor = kb.anyValue( kb.sym(uri), ns.solid('profileHighlightColor') ) if (backgroundColor) break } // allow the parent element to define background by default backgroundColor = backgroundColor || 'transparent' mystyle += 'background-color: ' + backgroundColor + '; ' div.setAttribute('style', mystyle) } /// /////////////////////////// // Background metadata for this pane we bundle with the JS const individualForm = kb.sym( 'https://solid.github.io/solid-panes/contact/individualForm.ttl#form1' ) const individualFormDoc = individualForm.doc() if (!kb.holds(undefined, undefined, undefined, individualFormDoc)) { // If not loaded already // var individualFormText = require('./individualForm.js') $rdf.parse(_individualForm__WEBPACK_IMPORTED_MODULE_4___default.a, kb, individualFormDoc.uri, 'text/turtle') // Load form directly } const vcardOnt = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].vcard('Type').doc() if (!kb.holds(undefined, undefined, undefined, vcardOnt)) { // If not loaded already $rdf.parse(_vcard_js__WEBPACK_IMPORTED_MODULE_5__["default"], kb, vcardOnt.uri, 'text/turtle') // Load ontology directly } try { await kb.fetcher.load(subject.doc()) } catch (err) { complain('Error: Failed to load contact card: ' + err) } // end of try catch on load setPaneStyle() solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].checkUser() // kick off async operation @@@ use async version div.appendChild(Object(_mugshotGallery__WEBPACK_IMPORTED_MODULE_1__["renderMugshotGallery"])(dom, subject)) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].appendForm( dom, div, {}, subject, individualForm, subject.doc(), complainIfBad ) spacer() div.appendChild(await Object(_groupMembershipControl_js__WEBPACK_IMPORTED_MODULE_3__["renderGroupMemberships"])(subject, dataBrowserContext)) spacer() // Allow to attach documents etc to the contact card const editable = kb.updater.editable(subject.doc().uri, kb) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].attachmentList(dom, subject, div, { modify: editable // promptIcon: UI.icons.iconBase + 'noun_681601.svg', // predicate: UI.ns.vcard('url') // @@@@@@@@@ ,--- no, the vcard ontology structure uses a bnode. }) spacer() div.appendChild(await Object(_webidControl__WEBPACK_IMPORTED_MODULE_2__["renderWedidControl"])(subject, dataBrowserContext)) // div.appendChild(dom.createElement('hr')) } // renderIndividual /***/ }), /***/ "./node_modules/contacts-pane/individualForm.js": /*!******************************************************!*\ !*** ./node_modules/contacts-pane/individualForm.js ***! \******************************************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = ` # Now hand-edited @prefix rdf: . @prefix dct: . @prefix owl: . @prefix ui: . @prefix vcard: . @prefix pp: . @prefix : <#>. # Ontology additions or interpretations needed for the form to work well # The ontology file doesn't make them disjoint. This makes the selector be a choice. vcard:TelephoneType owl:disjointUnionOf ( vcard:Cell vcard:Home vcard:Work) . vcard:Type owl:disjointUnionOf (vcard:Home vcard:Work) . # for email # Better field labels vcard:Cell ui:label "mobile"@en . # app will imake nitial caps if nec vcard:hasAddress ui:label "address"@en . vcard:bday ui:label "born"@en. vcard:hasEmail ui:label "email"@en . vcard:hasTelephone ui:label "phone"@en . vcard:note ui:label "notes"@en . # The forms themselves vcard:Individual ui:creationForm :form1 . # The addressComment, etc., fields with a comment before each type of field # were originally partly because the labels on the fields were clumsy like "hasAddress". # This is fixed by adding the ui:label to the properties above, so let's try # removing the little micro-headings :form1 dct:title "Contact Details" ; a ui:Form ; ui:part :fullNameField, :roleField, :fullNameFieldC, :paymentPointerField, :addressesComment, :addresses, :emailComment, :eMails, :telephoneComment, :telephones, :noteComment, :noteField ; ui:parts ( :fullNameField :roleField :fullNameFieldC :paymentPointerField # :addressesComment :addresses # :emailComment :eMails # :telephoneComment :telephones :birthdayField # :noteComment :noteField ) . :fullNameField a ui:SingleLineTextField ; ui:label "Name"; ui:maxLength "128" ; ui:property vcard:fn ; ui:size "40" . :roleField a ui:SingleLineTextField ; ui:suppressEmptyUneditable true; ui:maxLength "128" ; ui:property vcard:role ; ui:size "40" . :fullNameFieldC a ui:SingleLineTextField ; ui:suppressEmptyUneditable true; ui:maxLength "128" ; ui:property vcard:organization-name ; ui:size "40" . :paymentPointerField a ui:SingleLineTextField ; ui:maxLength "128" ; ui:property pp:PaymentPointer ; ui:size "40" . :addressesComment a ui:Comment ; ui:suppressIfUneditable true; ui:contents "Address" . :addresses dct:title "Address details" ; a ui:Multiple ; ui:part :oneAddress ; ui:property vcard:hasAddress . :oneAddress a ui:Group ; ui:parts ( :id1409437207443 :id1409437292400 :id1409437421996 :id1409437467649 :id1409437569420 :id1409437646712 ). :id1409437207443 a ui:SingleLineTextField ; ui:maxLength "128" ; ui:property vcard:street-address ; ui:size "40" . :id1409437292400 a ui:SingleLineTextField ; ui:maxLength "128" ; ui:property vcard:locality ; ui:size "40" . :id1409437421996 a ui:SingleLineTextField ; ui:maxLength "25" ; ui:property vcard:postal-code ; ui:size "25" . :id1409437467649 a ui:SingleLineTextField ; ui:maxLength "128" ; ui:property vcard:region ; ui:size "40" . :id1409437569420 a ui:SingleLineTextField ; ui:maxLength "128" ; ui:property vcard:country-name ; ui:size "40" . :id1409437646712 a ui:Classifier ; ui:from rdf:Class ; ui:property rdf:type . ############################## :emailComment a ui:Comment ; ui:suppressIfUneditable true; ui:contents "Email" . :eMails a ui:Multiple ; ui:part :oneEMail ; ui:property vcard:hasEmail . :oneEMail a ui:Group ; # hint: side by side is good ui:part :emailValue, :emailType ; ui:parts ( :emailType :emailValue ). :emailValue a ui:EmailField ; ui:label "email"; ui:property vcard:value ; ui:size "50" . :emailType a ui:Classifier ; ui:canMintNew "0" ; ui:category vcard:Type ; ui:from vcard:Type ; ui:property rdf:type . ############################## :telephoneComment a ui:Comment ; ui:suppressIfUneditable true; ui:contents "Phones" . :telephones a ui:Multiple ; ui:part :onetelephone ; ui:property vcard:hasTelephone . :onetelephone a ui:Group ; ui:part :telephoneValue, :telephoneType ; ui:parts ( :telephoneType :telephoneValue ). :telephoneValue a ui:PhoneField ; ui:property vcard:value ; ui:size "50" . :telephoneType a ui:Classifier ; ui:canMintNew "0" ; ui:category vcard:TelephoneType ; ui:from vcard:Type ; ui:property rdf:type . ############################## :birthdayField a ui:DateField; ui:label "Born"; ui:suppressEmptyUneditable true; ui:property vcard:bday . ############################## :noteComment a ui:Comment ; ui:suppressIfUneditable true; ui:contents "General Notes" . :noteField a ui:MultiLineTextField ; ui:suppressEmptyUneditable true; ui:property vcard:note . ` /***/ }), /***/ "./node_modules/contacts-pane/mintNewAddressBook.js": /*!**********************************************************!*\ !*** ./node_modules/contacts-pane/mintNewAddressBook.js ***! \**********************************************************/ /*! exports provided: mintNewAddressBook */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mintNewAddressBook", function() { return mintNewAddressBook; }); const UI = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js") // const mime = require('mime-types') // const toolsPane0 = require('./toolsPane') // const toolsPane = toolsPane0.toolsPane const $rdf = UI.rdf // const ns = UI.ns // const utils = UI.utils // Mint a new address book function mintNewAddressBook (dataBrowserContext, context) { return new Promise(function (resolve, reject) { UI.authn.logInLoadProfile(context).then( context => { // 20180713 console.log('Logged in as ' + context.me) const me = context.me const dom = context.dom const div = context.div const kb = dataBrowserContext.session.store const ns = UI.ns const newBase = context.newBase || context.newInstance.dir().uri const instanceClass = context.instanceClass || ns.vcard('AddressBook') if (instanceClass.sameTerm(ns.vcard('Group'))) { // Make a group not an address book const g = context.newInstance || kb.sym(context.newBase + 'index.ttl#this') const doc = g.doc() kb.add(g, ns.rdf('type'), ns.vcard('Group'), doc) kb.add( g, ns.vcard('fn'), context.instanceName || 'untitled group', doc ) // @@ write doc back kb.fetcher .putBack(doc, { contentType: 'text/turtle' }) .then(function (_xhr) { resolve(context) }) .catch(function (err) { reject( new Error('Error creating document for new group ' + err) ) }) return } const appInstanceNoun = 'address book' function complain (message) { div.appendChild(UI.widgets.errorMessageBlock(dom, message, 'pink')) } let bookContents = `@prefix vcard: . @prefix ab: . @prefix dc: . @prefix xsd: . <#this> a vcard:AddressBook; dc:title "New address Book"; vcard:nameEmailIndex ; vcard:groupIndex . ` bookContents += '<#this> <' + me.uri + '>.\n\n' const newAppInstance = kb.sym(newBase + 'index.ttl#this') const toBeWritten = [ { to: 'index.ttl', content: bookContents, contentType: 'text/turtle' }, { to: 'groups.ttl', content: '', contentType: 'text/turtle' }, { to: 'people.ttl', content: '', contentType: 'text/turtle' }, { to: '', existing: true, aclOptions: { defaultForNew: true } } ] // @@ Ask user abut ACLs? // // @@ Add header to PUT If-None-Match: * to prevent overwrite // function claimSuccess (newAppInstance, appInstanceNoun) { // @@ delete or grey other stuff console.log(`New ${appInstanceNoun} created at ${newAppInstance}`) const p = div.appendChild(dom.createElement('p')) p.setAttribute('style', 'font-size: 140%;') p.innerHTML = "Your new " + appInstanceNoun + ' is ready. ' + "

Go to new " + appInstanceNoun + '' const newContext = Object.assign( { newInstance: newAppInstance }, context ) resolve(newContext) } function doNextTask () { function checkOKSetACL (uri, ok) { if (!ok) { complain('Error writing new file ' + task.to) return reject(new Error('Error writing new file ' + task.to)) } UI.authn .setACLUserPublic(dest, me, aclOptions) .then(() => doNextTask()) .catch(err => { const message = 'Error setting access permissions for ' + task.to + ' : ' + err.message complain(message) return reject(new Error(message)) }) } if (toBeWritten.length === 0) { claimSuccess(newAppInstance, appInstanceNoun) } else { var task = toBeWritten.shift() /* eslint-disable-line no-var */ console.log('Creating new file ' + task.to + ' in new instance ') var dest = $rdf.uri.join(task.to, newBase) /* eslint-disable-line no-var */ var aclOptions = task.aclOptions || {} /* eslint-disable-line no-var */ if ('content' in task) { kb.fetcher .webOperation('PUT', dest, { data: task.content, saveMetadata: true, contentType: task.contentType }) .then(() => checkOKSetACL(dest, true)) } else if ('existing' in task) { checkOKSetACL(dest, true) } else { reject(new Error('copy not expected buiding new app!!')) // const from = task.from || task.to // default source to be same as dest // UI.widgets.webCopy(base + from, dest, task.contentType, checkOKSetACL) } } } doNextTask() }, err => { // log in then context.div.appendChild(UI.widgets.errorMessageBlock(err)) } ) }) } /***/ }), /***/ "./node_modules/contacts-pane/mugshotGallery.js": /*!******************************************************!*\ !*** ./node_modules/contacts-pane/mugshotGallery.js ***! \******************************************************/ /*! exports provided: renderMugshotGallery */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderMugshotGallery", function() { return renderMugshotGallery; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var mime_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! mime-types */ "./node_modules/mime-types/index.js"); /* harmony import */ var mime_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(mime_types__WEBPACK_IMPORTED_MODULE_1__); const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const utils = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] /* Mugshot Gallery * * A widget for managing a set of images. * Make this a form field? */ function renderMugshotGallery (dom, subject) { function complain (message) { console.log(message) galleryDiv.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message, 'pink')) } async function linkToPicture (subject, pic, remove) { const link = [ $rdf.st(subject, ns.vcard('hasPhoto'), pic, subject.doc()) ] try { if (remove) { await kb.updater.update(link, []) } else { await kb.updater.update([], link) } } catch (err) { const msg = ' Write back image link FAIL ' + pic + ', Error: ' + err console.log(msg) alert(msg) } } function handleDroppedThing (thing) { kb.fetcher.nowOrWhenFetched(thing.doc(), function (ok, mess) { if (!ok) { console.log('Error looking up dropped thing ' + thing + ': ' + mess) } else { const types = kb.findTypeURIs(thing) for (const ty in types) { console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped? } console.log('Default: assume web page ' + thing) // icon was: UI.icons.iconBase + 'noun_25830.svg' kb.add(subject, ns.wf('attachment'), thing, subject.doc()) // @@ refresh UI } }) } function uploadFileToContact (filename, contentType, data) { // const fileExtension = filename.split('.').pop() // .toLowerCase() const extension = mime_types__WEBPACK_IMPORTED_MODULE_1__["extension"](contentType) if (contentType !== mime_types__WEBPACK_IMPORTED_MODULE_1__["lookup"](filename)) { filename += '_.' + extension console.log('MIME TYPE MISMATCH -- adding extension: ' + filename) } let prefix, predicate const isImage = contentType.startsWith('image') if (isImage) { prefix = 'image_' predicate = ns.vcard('hasPhoto') } else { prefix = 'attachment_' predicate = ns.wf('attachment') } let n, pic for (n = 0; ; n++) { // Check filename is not used or invent new one pic = kb.sym(subject.dir().uri + filename) if (!kb.holds(subject, ns.vcard('hasPhoto'), pic)) { break } filename = prefix + n + '.' + extension } console.log( 'Putting ' + data.byteLength + ' bytes of ' + contentType + ' to ' + pic ) kb.fetcher .webOperation('PUT', pic.uri, { data: data, contentType: contentType }) .then(function (response) { if (!response.ok) { complain('Error uploading ' + pic + ':' + response.status) return } console.log(' Upload: put OK: ' + pic) kb.add(subject, predicate, pic, subject.doc()) kb.fetcher .putBack(subject.doc(), { contentType: 'text/turtle' }) .then( function (_response) { if (isImage) { mugshotDiv.refresh() } }, function (err) { console.log( ' Write back image link FAIL ' + pic + ', Error: ' + err ) } ) }) } // When a set of URIs are dropped on function handleURIsDroppedOnMugshot (uris) { uris.forEach(function (u) { const thing = $rdf.sym(u) // Attachment needs text label to disinguish I think not icon. console.log('Dropped on mugshot thing ' + thing) // icon was: UI.icons.iconBase + 'noun_25830.svg' if (u.startsWith('http') && u.indexOf('#') < 0) { // Plain document // Take a copy of a photo on the web: const options = { withCredentials: false, credentials: 'omit' } kb.fetcher.webOperation('GET', thing.uri, options).then( result => { const contentType = result.headers.get('Content-Type') // let data = result.responseText let pathEnd = thing.uri.split('/').slice(-1)[0] // last segment as putative filename pathEnd = pathEnd.split('?')[0] // chop off any query params result.arrayBuffer().then(function (data) { // read text stream if (!result.ok) { complain('Error downloading ' + thing + ':' + result.status) return } uploadFileToContact(pathEnd, contentType, data) }) }, err => { complain( `WebOp (fetch) error trying to read picture ${thing} on web: ${err}` ) } ) return } else { console.log( 'Not a web document URI, cannot copy as picture: ' + thing ) } handleDroppedThing(thing) }) } // Drop an image file to set up the mugshot function droppedFileHandler (files) { for (let i = 0; i < files.length; i++) { const f = files[i] console.log( ' contacts: Filename: ' + f.name + ', type: ' + (f.type || 'n/a') + ' size: ' + f.size + ' bytes, last modified: ' + (f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a') ) // See e.g. https://www.html5rocks.com/en/tutorials/file/dndfiles/ // @@ Add: progress bar(s) const reader = new FileReader() reader.onload = (function (theFile) { return function (e) { const data = e.target.result console.log(' File read byteLength : ' + data.byteLength) const filename = encodeURIComponent(theFile.name) const contentType = theFile.type uploadFileToContact(filename, contentType, data) } })(f) reader.readAsArrayBuffer(f) } } function elementForImage (image) { const img = dom.createElement('img') img.setAttribute( 'style', 'max-height: 10em; border-radius: 1em; margin: 0.7em;' ) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDropTarget( img, handleURIsDroppedOnMugshot, droppedFileHandler ) if (image) { img.setAttribute('src', image.uri) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDraggable(img, image) } return img } function syncMugshots () { let images = kb.each(subject, ns.vcard('hasPhoto')) // Priviledge vcard ones images.sort() // arbitrary consistency images = images.slice(0, 5) // max number for the space if (images.length === 0) { mugshotDiv.innerHTML = '' // strictly, don't remove it if already there if (editable) { mugshotDiv.appendChild(placeholder) // A head image to drop pictures on } // otherwise leave gallery empty .. nothing to see here folks } else { utils.syncTableToArray(mugshotDiv, images, elementForImage) } } // Good URI for a Camera picture function getImageDoc () { const imageDoc = kb.sym( subject.dir().uri + 'Image_' + Date.now() + '.png' ) return imageDoc } // Store picture async function tookPicture (imageDoc) { if (imageDoc) { await linkToPicture(subject, imageDoc) syncMugshots() } } function trashCan () { const button = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].button( dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_925021.svg', 'Drag here to delete' ) async function droppedURIHandler (uris) { const images = kb .each(subject, ns.vcard('hasPhoto')) .map(x => x.uri) for (const uri of uris) { if (!images.includes(uri)) { alert('Only drop images in this contact onto this trash can.') return } if (confirm(`Permanently DELETE image ${uri} completely?`)) { console.log('Unlinking image file ' + uri) await linkToPicture(subject, kb.sym(uri), true) try { console.log('Deleting image file ' + uri) await kb.fetcher.webOperation('DELETE', uri) } catch (err) { alert('Unable to delete picture! ' + err) } } } syncMugshots() } solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDropTarget(button, droppedURIHandler, null) return button } function renderImageTools () { const imageToolTable = dom.createElement('table') const row = imageToolTable.appendChild(dom.createElement('tr')) const left = row.appendChild(dom.createElement('td')) const middle = row.appendChild(dom.createElement('td')) const right = row.appendChild(dom.createElement('td')) left.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["media"].cameraButton(dom, kb, getImageDoc, tookPicture) ) // 20190812 try { middle.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].fileUploadButtonDiv(dom, droppedFileHandler) ) } catch (e) { console.log('ignore fileUploadButtonDiv error for now', e) } right.appendChild(trashCan()) return imageToolTable } // Body of renderMugshotGallery const editable = kb.updater.editable(subject.doc().uri, kb) const galleryDiv = dom.createElement('div') const mugshotDiv = galleryDiv.appendChild(dom.createElement('div')) const placeholder = elementForImage() solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].setImage(placeholder, subject) // Fallback icon or get from web syncMugshots() mugshotDiv.refresh = syncMugshots if (editable) { galleryDiv.appendChild(renderImageTools()) } return galleryDiv } /***/ }), /***/ "./node_modules/contacts-pane/toolsPane.js": /*!*************************************************!*\ !*** ./node_modules/contacts-pane/toolsPane.js ***! \*************************************************/ /*! exports provided: toolsPane */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toolsPane", function() { return toolsPane; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _contactLogic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./contactLogic */ "./node_modules/contacts-pane/contactLogic.js"); // The tools pane is for managing and debugging and maintaining solid contacts databases // /* global confirm, $rdf */ function toolsPane ( selectAllGroups, selectedGroups, groupsMainTable, book, dataBrowserContext, me ) { const dom = dataBrowserContext.dom const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const VCARD = ns.vcard const buttonStyle = 'font-size: 100%; margin: 0.8em; padding:0.5em;' const pane = dom.createElement('div') const table = pane.appendChild(dom.createElement('table')) table.setAttribute( 'style', 'font-size:120%; margin: 1em; border: 0.1em #ccc ;' ) const headerRow = table.appendChild(dom.createElement('tr')) headerRow.textContent = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(book) + ' - tools' headerRow.setAttribute( 'style', 'min-width: 20em; padding: 1em; font-size: 150%; border-bottom: 0.1em solid red; margin-bottom: 2em;' ) const statusRow = table.appendChild(dom.createElement('tr')) const statusBlock = statusRow.appendChild(dom.createElement('div')) statusBlock.setAttribute('style', 'padding: 2em;') const MainRow = table.appendChild(dom.createElement('tr')) const box = MainRow.appendChild(dom.createElement('table')) table.appendChild(dom.createElement('tr')) // bottomRow const context = { target: book, me: me, noun: 'address book', div: pane, dom: dom, statusRegion: statusBlock } function complain (message) { console.log(message) statusBlock.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message, 'pink')) } // Body of main pane function async function main () { box.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["aclControl"].ACLControlBox5( book.dir(), dataBrowserContext, 'book', kb, function (ok, body) { if (!ok) box.innerHTML = 'ACL control box Failed: ' + body } ) ) // try { await solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].registrationControl(context, book, ns.vcard('AddressBook')) } catch (e) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].complain(context, 'registrationControl: ' + e) } console.log('Registration control finished.') // Output stats in line mode form const logSpace = MainRow.appendChild(dom.createElement('pre')) function log (message) { console.log(message) logSpace.textContent += message + '\n' } function stats () { const totalCards = kb.each(undefined, VCARD('inAddressBook'), book).length log('' + totalCards + ' cards loaded. ') const groups = kb.each(book, VCARD('includesGroup')) log('' + groups.length + ' total groups. ') const gg = [] for (const g in selectedGroups) { gg.push(g) } log('' + gg.length + ' selected groups. ') } async function loadIndexHandler (_event) { loadIndexButton.setAttribute('style', 'background-color: #ffc;') const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex')) try { await kb.fetcher.load(nameEmailIndex) } catch (e) { loadIndexButton.setAttribute('style', 'background-color: #fcc;') log('Error: People index has NOT been loaded' + e + '\n') } loadIndexButton.setAttribute('style', 'background-color: #cfc;') log(' People index has been loaded\n') } // loadIndexHandler const loadIndexButton = pane.appendChild(dom.createElement('button')) loadIndexButton.textContent = 'Load main index' loadIndexButton.style.cssText = buttonStyle loadIndexButton.addEventListener('click', loadIndexHandler) const statButton = pane.appendChild(dom.createElement('button')) statButton.textContent = 'Statistics' statButton.style.cssText = buttonStyle statButton.addEventListener('click', stats) const checkAccessButton = pane.appendChild(dom.createElement('button')) checkAccessButton.textContent = 'Check individual card access of selected groups' checkAccessButton.style.cssText = buttonStyle async function checkAcces (_event) { function doCard (card) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].fixIndividualCardACL(card, log, function (ok, message) { if (ok) { log('Success for ' + solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(card)) } else { log('Failure for ' + solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(card) + ': ' + message) } }) } const gg = [] for (const g in selectedGroups) { gg.push(g) } for (let i = 0; i < gg.length; i++) { const g = kb.sym(gg[i]) const a = kb.each(g, ns.vcard('hasMember')) log(solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(g) + ': ' + a.length + ' members') for (let j = 0; j < a.length; j++) { const card = a[j] log(solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(card)) doCard(card) } } } checkAccessButton.addEventListener('click', checkAcces) // /////////////////////////////////////////////////////////////////////////// // // DUPLICATES CHECK const checkDuplicates = pane.appendChild(dom.createElement('button')) checkDuplicates.textContent = 'Find duplicate cards' checkDuplicates.style.cssText = buttonStyle checkDuplicates.addEventListener('click', function (_event) { const stats = {} // global god context stats.book = book stats.nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex')) log('Loading name index...') solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"].fetcher.nowOrWhenFetched( stats.nameEmailIndex, undefined, function (_ok, _message) { log('Loaded name index.') stats.cards = [] stats.duplicates = [] stats.definitive = [] stats.nameless = [] stats.exactDuplicates = [] stats.nameOnlyDuplicates = [] stats.uniquesSet = [] stats.groupProblems = [] // Erase one card and all its files -> (err) // /* function eraseOne (card) { return new Promise(function (resolve, reject) { function removeFromMainIndex () { var indexBit = kb.connectedStatements(card, stats.nameEmailIndex) log('Bits of the name index file:' + indexBit) log('Patching main index file...') kb.updater.update(indexBit, [], function (uri, ok, body) { if (ok) { log('Success') resolve(null) } else { log('Error patching index file! ' + body) reject('Error patching index file! ' + body) } }) } var filesToDelete = [ card.doc() ] var photos = kb.each(card, ns.vcard('hasPhoto')) // could be > 1 if (photos.length) { filesToDelete = filesToDelete.concat(photos) } filesToDelete.push(card.dir()) // the folder last log('Files to delete: ' + filesToDelete) if (!confirm('DELETE card ' + card.dir() + ' for "' + kb.any(card, VCARD('fn')) + '", with ' + kb.each(card).length + 'statements?')) { return resolve('Cancelled by user') } function deleteNextFile () { var resource = filesToDelete.shift() if (!resource) { log('All deleted') removeFromMainIndex() resolve() } log('Deleting ... ' + resource) kb.fetcher.delete(resource) .then(function () { log('Deleted ok: ' + resource) deleteNextFile() }) .catch(function (e) { var err = '*** ERROR deleting ' + resource + ': ' + e log(err) if (confirm('Patch out index file for card ' + card.dir() + ' EVEN THOUGH card DELETE errors?')) { removeFromMainIndex() } else { reject(err) } }) } deleteNextFile() }) // Promise } // erase one */ // Check actual records to see which are exact matches - slow stats.nameDupLog = kb.sym(book.dir().uri + 'dedup-nameDupLog.ttl') stats.exactDupLog = kb.sym(book.dir().uri + 'dedup-exactDupLog.ttl') /* function checkOne (card) { return new Promise(function (resolve, reject) { var name = kb.anyValue(card, ns.vcard('fn')) var other = stats.definitive[name] kb.fetcher.load([card, other]).then(function (xhrs) { var exclude = {} exclude[ns.vcard('hasUID').uri] = true exclude[ns.dc('created').uri] = true exclude[ns.dc('modified').uri] = true function filtered (x) { return kb.statementsMatching(null, null, null, x.doc()).filter(function (st) { return !exclude[st.predicate.uri] }) } var desc = filtered(card) var desc2 = filtered(other) // var desc = connectedStatements(card, card.doc(), exclude) // var desc2 = connectedStatements(other, other.doc(), exclude) if (desc.length !== desc2.length) { log('CARDS to NOT match lengths ') stats.nameOnlyDuplicates.push(card) return resolve(false) } if (!desc.length) { log('@@@@@@ Zero length ') stats.nameOnlyDuplicates.push(card) return resolve(false) } // //////// Compare the two // Cheat: serialize and compare // var cardText = $rdf.serialize(card.doc(), kb, card.doc().uri, 'text/turtle') // var otherText = $rdf.serialize(other.doc(), kb, other.doc().uri, 'text/turtle') var cardText = (new $rdf.Serializer(kb)).setBase(card.doc().uri).statementsToN3(desc) var otherText = (new $rdf.Serializer(kb)).setBase(other.doc().uri).statementsToN3(desc2) // // log('Name: ' + name + ', statements: ' + desc.length) // log('___________________________________________') // log('KEEPING: ' + other.doc() + '\n' + cardText) // log('___________________________________________') // log('DELETING: '+ card.doc() + '\n' + otherText) // log('___________________________________________') // if (cardText !== otherText) { log('Texts differ') stats.nameOnlyDuplicates.push(card) return resolve(false) } var cardGroups = kb.each(null, ns.vcard('hasMember'), card) var otherGroups = kb.each(null, ns.vcard('hasMember'), other) for (var j = 0; j < cardGroups.length; j++) { var found = false for (var k = 0; k < otherGroups.length; k++) { if (otherGroups[k].sameTerm(cardGroups[j])) { found = true } } if (!found) { log('This one groups: ' + cardGroups) log('Other one groups: ' + otherGroups) log('Cant delete this one because it has a group, ' + cardGroups[j] + ', which the other does not.') stats.nameOnlyDuplicates.push(card) return resolve(false) } } console.log('Group check done -- exact duplicate: ' + card) stats.exactDuplicates.push(card) resolve(true) }).catch(function (e) { log('Cant load a card! ' + [card, other] + ': ' + e) stats.nameOnlyDuplicates.push(card) resolve(false) // if (confirm('Patch out index file for card ' + card.dir() + ' EVEN THOUGH card READ errors?')){ // removeFromMainIndex() // } }) }) } // checkOne */ stats.nameOnlyErrors = [] stats.nameLessZeroData = [] stats.nameLessIndex = [] stats.namelessUniques = [] stats.nameOnlyDuplicatesGroupDiff = [] function checkOneNameless (card) { return new Promise(function (resolve) { kb.fetcher .load(card) .then(function (_xhr) { log(' Nameless check ' + card) const exclude = {} exclude[ns.vcard('hasUID').uri] = true exclude[ns.dc('created').uri] = true exclude[ns.dc('modified').uri] = true function filtered (x) { return kb .statementsMatching(null, null, null, x.doc()) .filter(function (st) { return !exclude[st.predicate.uri] }) } const desc = filtered(card) // var desc = connectedStatements(card, card.doc(), exclude) // var desc2 = connectedStatements(other, other.doc(), exclude) if (!desc.length) { log(' Zero length ' + card) stats.nameLessZeroData.push(card) return resolve(false) } // Compare the two // Cheat: serialize and compare // var cardText = $rdf.serialize(card.doc(), kb, card.doc().uri, 'text/turtle') // var otherText = $rdf.serialize(other.doc(), kb, other.doc().uri, 'text/turtle') const cardText = new $rdf.Serializer(kb) .setBase(card.doc().uri) .statementsToN3(desc) const other = stats.nameLessIndex[cardText] if (other) { log(' Matches with ' + other) const cardGroups = kb.each(null, ns.vcard('hasMember'), card) const otherGroups = kb.each(null, ns.vcard('hasMember'), other) for (let j = 0; j < cardGroups.length; j++) { let found = false for (let k = 0; k < otherGroups.length; k++) { if (otherGroups[k].sameTerm(cardGroups[j])) found = true } if (!found) { log('This one groups: ' + cardGroups) log('Other one groups: ' + otherGroups) log( 'Cant skip this one because it has a group, ' + cardGroups[j] + ', which the other does not.' ) stats.nameOnlyDuplicatesGroupDiff.push(card) return resolve(false) } } console.log('Group check done -- exact duplicate: ' + card) } else { log('First nameless like: ' + card.doc()) log('___________________________________________') log(cardText) log('___________________________________________') stats.nameLessIndex[cardText] = card stats.namelessUniques.push(card) } resolve(true) }) .catch(function (e) { log('Cant load a nameless card!: ' + e) stats.nameOnlyErrors.push(card) resolve(false) }) }) } // checkOneNameless function checkAllNameless () { stats.namelessToCheck = stats.namelessToCheck || stats.nameless.slice() log('Nameless check left: ' + stats.namelessToCheck.length) return new Promise(function (resolve) { const x = stats.namelessToCheck.shift() if (!x) { log('namelessUniques: ' + stats.namelessUniques.length) log('namelessUniques: ' + stats.namelessUniques) if (stats.namelessUniques.length > 0 && confirm( 'Add all ' + stats.namelessUniques.length + ' nameless cards to the rescued set?' ) ) { stats.uniques = stats.uniques.concat(stats.namelessUniques) for (let k = 0; k < stats.namelessUniques.length; k++) { stats.uniqueSet[stats.namelessUniques[k].uri] = true } } return resolve(true) } checkOneNameless(x).then(function (exact) { log(' Nameless check returns ' + exact) checkAllNameless() // loop }) }) } function checkGroupMembers () { return new Promise(function (resolve) { // var inUniques = 0 log('Groups loaded') for (let i = 0; i < stats.uniques.length; i++) { stats.uniquesSet[stats.uniques[i].uri] = true } stats.groupMembers = kb .statementsMatching(null, ns.vcard('hasMember')) .map(st => st.object) log(' Naive group members ' + stats.groupMembers.length) stats.groupMemberSet = [] for (let j = 0; j < stats.groupMembers.length; j++) { stats.groupMemberSet[stats.groupMembers[j].uri] = stats.groupMembers[j] } stats.groupMembers2 = [] for (const g in stats.groupMemberSet) { stats.groupMembers2.push(stats.groupMemberSet[g]) } log(' Compact group members ' + stats.groupMembers2.length) if ( $rdf.keepThisCodeForLaterButDisableFerossConstantConditionPolice ) { // Don't inspect as seems groups membership is complete for (let i = 0; i < stats.groupMembers.length; i++) { const card = stats.groupMembers[i] if (stats.uniquesSet[card.uri]) { // inUniques += 1 } else { log(' Not in uniques: ' + card) stats.groupProblems.push(card) if (stats.duplicateSet[card.uri]) { log(' ** IN duplicates alas:' + card) } else { log(' **** WTF?') } } } log('Problem cards: ' + stats.groupProblems.length) } // if resolve(true) }) } // checkGroupMembers function scanForDuplicates () { return new Promise(function (resolve) { stats.cards = kb.each(undefined, VCARD('inAddressBook'), stats.book) log('' + stats.cards.length + ' total cards') let c, card, name for (c = 0; c < stats.cards.length; c++) { card = stats.cards[c] name = kb.anyValue(card, ns.vcard('fn')) if (!name) { stats.nameless.push(card) continue } if (stats.definitive[name] === card) { // pass } else if (stats.definitive[name]) { const n = stats.duplicates.length if (n < 100 || (n < 1000 && n % 10 === 0) || n % 100 === 0) { // log('' + n + ') Possible duplicate ' + card + ' of: ' + definitive[name]) } stats.duplicates.push(card) } else { stats.definitive[name] = card } } stats.duplicateSet = [] for (let i = 0; i < stats.duplicates.length; i++) { stats.duplicateSet[stats.duplicates[i].uri] = stats.duplicates[i] } stats.namelessSet = [] for (let i = 0; i < stats.nameless.length; i++) { stats.namelessSet[stats.nameless[i].uri] = stats.nameless[i] } stats.uniques = [] stats.uniqueSet = [] for (let i = 0; i < stats.cards.length; i++) { const uri = stats.cards[i].uri if (!stats.duplicateSet[uri] && !stats.namelessSet[uri]) { stats.uniques.push(stats.cards[i]) stats.uniqueSet[uri] = stats.cards[i] } } log('Uniques: ' + stats.uniques.length) log('' + stats.nameless.length + ' nameless cards.') log( '' + stats.duplicates.length + ' name-duplicate cards, leaving ' + (stats.cards.length - stats.duplicates.length) ) resolve(true) }) } // Save a new clean version function saveCleanPeople () { let cleanPeople return Promise.resolve() .then(() => { cleanPeople = kb.sym(stats.book.dir().uri + 'clean-people.ttl') let sts = [] for (let i = 0; i < stats.uniques.length; i++) { sts = sts.concat( kb.connectedStatements(stats.uniques[i], stats.nameEmailIndex) ) } const sz = new $rdf.Serializer(kb).setBase(stats.nameEmailIndex.uri) log('Serializing index of uniques...') const data = sz.statementsToN3(sts) return kb.fetcher.webOperation('PUT', cleanPeople, { data: data, contentType: 'text/turtle' }) }) .then(function () { log('Done uniques log ' + cleanPeople) return true }) .catch(function (e) { log('Error saving uniques: ' + e) }) } function saveCleanGroup (g) { let cleanGroup return Promise.resolve() .then(() => { const s = g.uri.replace('/Group/', '/NewGroup/') cleanGroup = kb.sym(s) let sts = [] for (let i = 0; i < stats.uniques.length; i++) { sts = sts.concat( kb.connectedStatements(stats.uniques[i], g.doc()) ) } const sz = new $rdf.Serializer(kb).setBase(g.uri) log(' Regenerating group of uniques...' + cleanGroup) const data = sz.statementsToN3(sts) return kb.fetcher.webOperation('PUT', cleanGroup, { data }) }) .then(() => { log(' Done uniques group ' + cleanGroup) return true }) .catch(e => { log('Error saving : ' + e) }) } function saveAllGroups () { log('Saving ALL GROUPS') return Promise.all(stats.groupObjects.map(saveCleanGroup)) } const getAndSortGroups = function () { let groups = [] if (stats.book) { const books = [stats.book] books.forEach(function (book) { const gs = book ? kb.each(book, ns.vcard('includesGroup')) : [] const gs2 = gs.map(function (g) { return [book, kb.any(g, ns.vcard('fn')), g] }) groups = groups.concat(gs2) }) groups.sort() } return groups } const groups = getAndSortGroups() // Needed? stats.groupObjects = groups.map(gstr => gstr[2]) log('Loading ' + stats.groupObjects.length + ' groups... ') kb.fetcher .load(stats.groupObjects) .then(scanForDuplicates) .then(checkGroupMembers) .then(checkAllNameless) .then((resolve, reject) => { if (confirm('Write new clean versions?')) { resolve(true) } else { reject() } }) .then(saveCleanPeople) .then(saveAllGroups) .then(function () { log('Done!') }) } ) }) async function fixGroupless (book) { const groupless = await getGroupless(book) if (groupless.length === 0) { log('No groupless cards found.') return } const groupOfUngrouped = await Object(_contactLogic__WEBPACK_IMPORTED_MODULE_1__["saveNewGroup"])(book, 'ZSortThese') if (confirm(`Add the ${groupless.length} cards without groups to a ZSortThese group?`)) { for (const person of groupless) { log(' adding ' + person) await Object(_contactLogic__WEBPACK_IMPORTED_MODULE_1__["addPersonToGroup"])(person, groupOfUngrouped) } } log('People moved to group.') } async function getGroupless (book) { const groupIndex = kb.any(book, ns.vcard('groupIndex')) const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex')) try { await kb.fetcher.load([nameEmailIndex, groupIndex]) const groups = kb.each(book, ns.vcard('includesGroup')) await kb.fetcher.load(groups) } catch (e) { complain('Error loading stuff:' + e) } const reverseIndex = {} const groupless = [] const groups = kb.each(book, VCARD('includesGroup')) log('' + groups.length + ' total groups. ') for (let i = 0; i < groups.length; i++) { const g = groups[i] const a = kb.each(g, ns.vcard('hasMember')) log(solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(g) + ': ' + a.length + ' members') for (let j = 0; j < a.length; j++) { kb.allAliases(a[j]).forEach(function (y) { reverseIndex[y.uri] = g }) } } const cards = kb.each(undefined, VCARD('inAddressBook'), book) log('' + cards.length + ' total cards') for (let c = 0; c < cards.length; c++) { if (!reverseIndex[cards[c].uri]) { groupless.push(cards[c]) log(' groupless ' + solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(cards[c])) } } log('' + groupless.length + ' groupless cards.') return groupless } const checkGroupless = pane.appendChild(dom.createElement('button')) checkGroupless.style.cssText = buttonStyle checkGroupless.textContent = 'Find individuals with no group' checkGroupless.addEventListener('click', function (_event) { log('Loading groups...') selectAllGroups(selectedGroups, groupsMainTable, async function (ok, message) { if (!ok) { log('Load all groups: failed: ' + message) return } const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex')) try { await kb.fetcher.load(nameEmailIndex) } catch (e) { complain(e) } log('Loaded groups and name index.') getGroupless(book) log('Groupless list finished..') }) // select all groups then }) const fixGrouplessButton = pane.appendChild(dom.createElement('button')) fixGrouplessButton.style.cssText = buttonStyle fixGrouplessButton.textContent = 'Put all individuals with no group in a new group' fixGrouplessButton.addEventListener('click', _event => fixGroupless(book)) } // main main() return pane } // toolsPane // ends /***/ }), /***/ "./node_modules/contacts-pane/vcard.js": /*!*********************************************!*\ !*** ./node_modules/contacts-pane/vcard.js ***! \*********************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (` @prefix : . @prefix owl: . @prefix rdf: . @prefix rdfs: . @prefix xml: . @prefix xsd: . :Acquaintance a owl:Class ; rdfs:label "Acquaintance"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Agent a owl:Class ; rdfs:label "Agent"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :BBS a owl:Class ; rdfs:label "BBS"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType ; owl:deprecated true . :Car a owl:Class ; rdfs:label "Car"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType ; owl:deprecated true . :Cell a owl:Class ; rdfs:label "Cell"@en ; rdfs:comment "Also called mobile telephone"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Child a owl:Class ; rdfs:label "Child"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Colleague a owl:Class ; rdfs:label "Colleague"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Contact a owl:Class ; rdfs:label "Contact"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Coresident a owl:Class ; rdfs:label "Coresident"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Coworker a owl:Class ; rdfs:label "Coworker"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Crush a owl:Class ; rdfs:label "Crush"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Date a owl:Class ; rdfs:label "Date"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Dom a owl:Class ; rdfs:label "Dom"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Emergency a owl:Class ; rdfs:label "Emergency"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Fax a owl:Class ; rdfs:label "Fax"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Female a owl:Class ; rdfs:label "Female"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Gender . :Friend a owl:Class ; rdfs:label "Friend"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Home a owl:Class ; rdfs:label "Home"@en ; rdfs:comment "This implies that the property is related to an individual's personal life"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type . :ISDN a owl:Class ; rdfs:label "ISDN"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Internet a owl:Class ; rdfs:label "Internet"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Intl a owl:Class ; rdfs:label "Intl"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Kin a owl:Class ; rdfs:label "Kin"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Label a owl:Class ; rdfs:label "Label"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Male a owl:Class ; rdfs:label "Male"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Gender . :Me a owl:Class ; rdfs:label "Me"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Met a owl:Class ; rdfs:label "Met"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Modem a owl:Class ; rdfs:label "Modem"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType ; owl:deprecated true . :Msg a owl:Class ; rdfs:label "Msg"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType ; owl:deprecated true . :Muse a owl:Class ; rdfs:label "Muse"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Neighbor a owl:Class ; rdfs:label "Neighbor"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :None a owl:Class ; rdfs:label "None"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Gender . :Other a owl:Class ; rdfs:label "Other"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Gender . :PCS a owl:Class ; rdfs:label "PCS"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType ; owl:deprecated true . :Pager a owl:Class ; rdfs:label "Pager"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Parcel a owl:Class ; rdfs:label "Parcel"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Parent a owl:Class ; rdfs:label "Parent"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Postal a owl:Class ; rdfs:label "Postal"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Pref a owl:Class ; rdfs:label "Pref"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :Sibling a owl:Class ; rdfs:label "Sibling"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Spouse a owl:Class ; rdfs:label "Spouse"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Sweetheart a owl:Class ; rdfs:label "Sweetheart"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :RelatedType . :Tel a owl:Class ; rdfs:label "Tel"@en ; rdfs:comment "This class is deprecated. Use the hasTelephone object property."@en ; rdfs:isDefinedBy ; owl:deprecated true . :Text a owl:Class ; rdfs:label "Text"@en ; rdfs:comment "Also called sms telephone"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :TextPhone a owl:Class ; rdfs:label "Text phone"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Unknown a owl:Class ; rdfs:label "Unknown"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Gender . :Video a owl:Class ; rdfs:label "Video"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Voice a owl:Class ; rdfs:label "Voice"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :TelephoneType . :Work a owl:Class ; rdfs:label "Work"@en ; rdfs:comment "This implies that the property is related to an individual's work place"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type . :X400 a owl:Class ; rdfs:label "X400"@en ; rdfs:comment "This class is deprecated"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Type ; owl:deprecated true . :adr a owl:ObjectProperty ; rdfs:label "address"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasAddress . :agent a owl:ObjectProperty ; rdfs:label "agent"@en ; rdfs:comment "This object property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :anniversary a owl:DatatypeProperty ; rdfs:label "anniversary"@en ; rdfs:comment "The date of marriage, or equivalent, of the object"@en ; rdfs:isDefinedBy ; rdfs:range [ a rdfs:Datatype ; owl:unionOf ( xsd:dateTime xsd:gYear ) ] . :bday a owl:DatatypeProperty ; rdfs:label "birth date"@en ; rdfs:comment "To specify the birth date of the object"@en ; rdfs:isDefinedBy ; rdfs:range [ a rdfs:Datatype ; owl:unionOf ( xsd:dateTime xsd:dateTimeStamp xsd:gYear ) ] . :category a owl:DatatypeProperty ; rdfs:label "category"@en ; rdfs:comment "The category information about the object, also known as tags"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :class a owl:DatatypeProperty ; rdfs:label "class"@en ; rdfs:comment "This data property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :email a owl:ObjectProperty ; rdfs:label "email"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasEmail . :extended-address a owl:DatatypeProperty ; rdfs:label "extended address"@en ; rdfs:comment "This data property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :geo a owl:ObjectProperty ; rdfs:label "geo"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasGeo . :hasAdditionalName a owl:ObjectProperty ; rdfs:label "has additional name"@en ; rdfs:comment "Used to support property parameters for the additional name data property"@en ; rdfs:isDefinedBy . :hasCalendarBusy a owl:ObjectProperty ; rdfs:label "has calendar busy"@en ; rdfs:comment "To specify the busy time associated with the object. (Was called FBURL in RFC6350)"@en ; rdfs:isDefinedBy . :hasCalendarLink a owl:ObjectProperty ; rdfs:label "has calendar link"@en ; rdfs:comment "To specify the calendar associated with the object. (Was called CALURI in RFC6350)"@en ; rdfs:isDefinedBy . :hasCalendarRequest a owl:ObjectProperty ; rdfs:label "has calendar request"@en ; rdfs:comment "To specify the calendar user address to which a scheduling request be sent for the object. (Was called CALADRURI in RFC6350)"@en ; rdfs:isDefinedBy . :hasCategory a owl:ObjectProperty ; rdfs:label "has category"@en ; rdfs:comment "Used to support property parameters for the category data property"@en ; rdfs:isDefinedBy . :hasCountryName a owl:ObjectProperty ; rdfs:label "has country name"@en ; rdfs:comment "Used to support property parameters for the country name data property"@en ; rdfs:isDefinedBy . :hasFN a owl:ObjectProperty ; rdfs:label "has formatted name"@en ; rdfs:comment "Used to support property parameters for the formatted name data property"@en ; rdfs:isDefinedBy . :hasFamilyName a owl:ObjectProperty ; rdfs:label "has family name"@en ; rdfs:comment "Used to support property parameters for the family name data property"@en ; rdfs:isDefinedBy . :hasGender a owl:ObjectProperty ; rdfs:label "has gender"@en ; rdfs:comment "To specify the sex or gender identity of the object. URIs are recommended to enable interoperable sex and gender codes to be used."@en ; rdfs:isDefinedBy . :hasGivenName a owl:ObjectProperty ; rdfs:label "has given name"@en ; rdfs:comment "Used to support property parameters for the given name data property"@en ; rdfs:isDefinedBy . :hasHonorificPrefix a owl:ObjectProperty ; rdfs:label "has honorific prefix"@en ; rdfs:comment "Used to support property parameters for the honorific prefix data property"@en ; rdfs:isDefinedBy . :hasHonorificSuffix a owl:ObjectProperty ; rdfs:label "has honorific suffix"@en ; rdfs:comment "Used to support property parameters for the honorific suffix data property"@en ; rdfs:isDefinedBy . :hasInstantMessage a owl:ObjectProperty ; rdfs:label "has messaging"@en ; rdfs:comment "To specify the instant messaging and presence protocol communications with the object. (Was called IMPP in RFC6350)"@en ; rdfs:isDefinedBy . :hasLanguage a owl:ObjectProperty ; rdfs:label "has language"@en ; rdfs:comment "Used to support property parameters for the language data property"@en ; rdfs:isDefinedBy . :hasLocality a owl:ObjectProperty ; rdfs:label "has locality"@en ; rdfs:comment "Used to support property parameters for the locality data property"@en ; rdfs:isDefinedBy . :hasNickname a owl:ObjectProperty ; rdfs:label "has nickname"@en ; rdfs:comment "Used to support property parameters for the nickname data property"@en ; rdfs:isDefinedBy ; rdfs:seeAlso :nickname . :hasNote a owl:ObjectProperty ; rdfs:label "has note"@en ; rdfs:comment "Used to support property parameters for the note data property"@en ; rdfs:isDefinedBy . :hasOrganizationName a owl:ObjectProperty ; rdfs:label "has organization name"@en ; rdfs:comment "Used to support property parameters for the organization name data property"@en ; rdfs:isDefinedBy . :hasOrganizationUnit a owl:ObjectProperty ; rdfs:label "has organization unit name"@en ; rdfs:comment "Used to support property parameters for the organization unit name data property"@en ; rdfs:isDefinedBy . :hasPostalCode a owl:ObjectProperty ; rdfs:label "has postal code"@en ; rdfs:comment "Used to support property parameters for the postal code data property"@en ; rdfs:isDefinedBy . :hasRegion a owl:ObjectProperty ; rdfs:label "has region"@en ; rdfs:comment "Used to support property parameters for the region data property"@en ; rdfs:isDefinedBy . :hasRelated a owl:ObjectProperty ; rdfs:label "has related"@en ; rdfs:comment "To specify a relationship between another entity and the entity represented by this object"@en ; rdfs:isDefinedBy . :hasRole a owl:ObjectProperty ; rdfs:label "has role"@en ; rdfs:comment "Used to support property parameters for the role data property"@en ; rdfs:isDefinedBy . :hasSource a owl:ObjectProperty ; rdfs:label "has source"@en ; rdfs:comment "To identify the source of directory information of the object"@en ; rdfs:isDefinedBy . :hasStreetAddress a owl:ObjectProperty ; rdfs:label "has street address"@en ; rdfs:comment "Used to support property parameters for the street address data property"@en ; rdfs:isDefinedBy . :hasTitle a owl:ObjectProperty ; rdfs:label "has title"@en ; rdfs:comment "Used to support property parameters for the title data property"@en ; rdfs:isDefinedBy . :hasUID a owl:ObjectProperty ; rdfs:label "has uid"@en ; rdfs:comment "To specify a value that represents a globally unique identifier corresponding to the object"@en ; rdfs:isDefinedBy . :hasValue a owl:ObjectProperty ; rdfs:label "has value"@en ; rdfs:comment "Used to indicate the resource value of an object property that requires property parameters"@en ; rdfs:isDefinedBy . :label a owl:DatatypeProperty ; rdfs:label "label"@en ; rdfs:comment "This data property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :language a owl:DatatypeProperty ; rdfs:label "language"@en ; rdfs:comment "To specify the language that may be used for contacting the object. May also be used as a property parameter."@en ; rdfs:isDefinedBy . :latitude a owl:DatatypeProperty ; rdfs:label "latitude"@en ; rdfs:comment "This data property has been deprecated. See hasGeo"@en ; rdfs:isDefinedBy ; owl:deprecated true . :longitude a owl:DatatypeProperty ; rdfs:label "longitude"@en ; rdfs:comment "This data property has been deprecated. See hasGeo"@en ; rdfs:isDefinedBy ; owl:deprecated true . :mailer a owl:DatatypeProperty ; rdfs:label "mailer"@en ; rdfs:comment "This data property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :note a owl:DatatypeProperty ; rdfs:label "note"@en ; rdfs:comment "A note associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :org a owl:ObjectProperty ; rdfs:label "organization"@en ; rdfs:comment "This object property has been mapped. Use the organization-name data property."@en ; rdfs:isDefinedBy ; owl:equivalentProperty :organization-name . :organization-unit a owl:DatatypeProperty ; rdfs:label "organizational unit name"@en ; rdfs:comment "To specify the organizational unit name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string ; rdfs:subPropertyOf :organization-name . :post-office-box a owl:DatatypeProperty ; rdfs:label "post office box"@en ; rdfs:comment "This data property has been deprecated"@en ; rdfs:isDefinedBy ; owl:deprecated true . :prodid a owl:DatatypeProperty ; rdfs:label "product id"@en ; rdfs:comment "To specify the identifier for the product that created the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :rev a owl:DatatypeProperty ; rdfs:label "revision"@en ; rdfs:comment "To specify revision information about the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:dateTime . :role a owl:DatatypeProperty ; rdfs:label "role"@en ; rdfs:comment "To specify the function or part played in a particular situation by the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :sort-string a owl:DatatypeProperty ; rdfs:label "sort as"@en ; rdfs:comment "To specify the string to be used for national-language-specific sorting. Used as a property parameter only."@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :title a owl:DatatypeProperty ; rdfs:label "title"@en ; rdfs:comment "To specify the position or job of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :tz a owl:DatatypeProperty ; rdfs:label "time zone"@en ; rdfs:comment "To indicate time zone information that is specific to the object. May also be used as a property parameter."@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :value a owl:DatatypeProperty ; rdfs:label "value"@en ; rdfs:comment "Used to indicate the literal value of a data property that requires property parameters"@en ; rdfs:isDefinedBy . :Address a owl:Class ; rdfs:label "Address"@en ; rdfs:comment "To specify the components of the delivery address for the object"@en ; rdfs:isDefinedBy ; owl:equivalentClass [ a owl:Class ; owl:unionOf ( [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :country-name ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :country-name ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :locality ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :locality ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :postal-code ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :postal-code ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :region ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :region ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :street-address ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :street-address ] ) ] ) ] . :Email a owl:Class ; rdfs:label "Email"@en ; rdfs:comment "To specify the electronic mail address for communication with the object the vCard represents. Use the hasEmail object property."@en ; rdfs:isDefinedBy ; owl:deprecated true . :Group a owl:Class ; rdfs:label "Group"@en ; rdfs:comment "Object representing a group of persons or entities. A group object will usually contain hasMember properties to specify the members of the group."@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Kind ; owl:disjointWith :Individual, :Location, :Organization ; owl:equivalentClass [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :hasMember ; owl:someValuesFrom :Kind ] [ a owl:Restriction ; owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onClass :Kind ; owl:onProperty :hasMember ] ) ] . :Individual a owl:Class ; rdfs:label "Individual"@en ; rdfs:comment "An object representing a single person or entity"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Kind ; owl:disjointWith :Location, :Organization . :Name a owl:Class ; rdfs:label "Name"@en ; rdfs:comment "To specify the components of the name of the object"@en ; rdfs:isDefinedBy ; owl:equivalentClass [ a owl:Class ; owl:unionOf ( [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :additional-name ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:minCardinality "0"^^xsd:nonNegativeInteger ; owl:onProperty :additional-name ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :family-name ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :family-name ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :given-name ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:maxCardinality "1"^^xsd:nonNegativeInteger ; owl:onProperty :given-name ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :honorific-prefix ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:minCardinality "0"^^xsd:nonNegativeInteger ; owl:onProperty :honorific-prefix ] ) ] [ a owl:Class ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty :honorific-suffix ; owl:someValuesFrom xsd:string ] [ a owl:Restriction ; owl:minCardinality "0"^^xsd:nonNegativeInteger ; owl:onProperty :honorific-suffix ] ) ] ) ] . :VCard a owl:Class ; rdfs:label "VCard"@en ; rdfs:comment "The vCard class is equivalent to the new Kind class, which is the parent for the four explicit types of vCards (Individual, Organization, Location, Group)"@en ; rdfs:isDefinedBy ; owl:equivalentClass :Kind . :fn a owl:DatatypeProperty ; rdfs:label "formatted name"@en ; rdfs:comment "The formatted text corresponding to the name of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :hasAddress a owl:ObjectProperty ; rdfs:label "has address"@en ; rdfs:comment "To specify the components of the delivery address for the object"@en ; rdfs:isDefinedBy ; rdfs:range :Address . :hasEmail a owl:ObjectProperty ; rdfs:label "has email"@en ; rdfs:comment "To specify the electronic mail address for communication with the object"@en ; rdfs:isDefinedBy ; rdfs:range :Email . :hasGeo a owl:ObjectProperty ; rdfs:label "has geo"@en ; rdfs:comment "To specify information related to the global positioning of the object. May also be used as a property parameter."@en ; rdfs:isDefinedBy . :hasKey a owl:ObjectProperty ; rdfs:label "has key"@en ; rdfs:comment "To specify a public key or authentication certificate associated with the object"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :key . :hasLogo a owl:ObjectProperty ; rdfs:label "has logo"@en ; rdfs:comment "To specify a graphic image of a logo associated with the object "@en ; rdfs:isDefinedBy ; owl:equivalentProperty :logo . :hasName a owl:ObjectProperty ; rdfs:label "has name"@en ; rdfs:comment "To specify the components of the name of the object"@en ; rdfs:isDefinedBy ; rdfs:range :Name ; owl:equivalentProperty :n . :hasPhoto a owl:ObjectProperty ; rdfs:label "has photo"@en ; rdfs:comment "To specify an image or photograph information that annotates some aspect of the object"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :photo . :hasSound a owl:ObjectProperty ; rdfs:label "has sound"@en ; rdfs:comment "To specify a digital sound content information that annotates some aspect of the object"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :sound . :hasTelephone a owl:ObjectProperty ; rdfs:label "has telephone"@en ; rdfs:comment "To specify the telephone number for telephony communication with the object"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :tel . :hasURL a owl:ObjectProperty ; rdfs:label "has url"@en ; rdfs:comment "To specify a uniform resource locator associated with the object"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :url . :key a owl:ObjectProperty ; rdfs:label "key"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasKey . :logo a owl:ObjectProperty ; rdfs:label "logo"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasLogo . :n a owl:ObjectProperty ; rdfs:label "name"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasName . :nickname a owl:DatatypeProperty ; rdfs:label "nickname"@en ; rdfs:comment "The nick name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :photo a owl:ObjectProperty ; rdfs:label "photo"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasPhoto . :sound a owl:ObjectProperty ; rdfs:label "sound"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasSound . :tel a owl:ObjectProperty ; rdfs:label "telephone"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasTelephone . :url a owl:ObjectProperty ; rdfs:label "url"@en ; rdfs:comment "This object property has been mapped"@en ; rdfs:isDefinedBy ; owl:equivalentProperty :hasURL . :Location a owl:Class ; rdfs:label "Location"@en ; rdfs:comment "An object representing a named geographical place"@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Kind ; owl:disjointWith :Organization . :additional-name a owl:DatatypeProperty ; rdfs:label "additional name"@en ; rdfs:comment "The additional name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :country-name a owl:DatatypeProperty ; rdfs:label "country name"@en ; rdfs:comment "The country name associated with the address of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :family-name a owl:DatatypeProperty ; rdfs:label "family name"@en ; rdfs:comment "The family name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :given-name a owl:DatatypeProperty ; rdfs:label "given name"@en ; rdfs:comment "The given name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :hasMember a owl:ObjectProperty ; rdfs:label "has member"@en ; rdfs:comment "To include a member in the group this object represents. (This property can only be used by Group individuals)"@en ; rdfs:domain :Group ; rdfs:isDefinedBy ; rdfs:range :Kind . :honorific-prefix a owl:DatatypeProperty ; rdfs:label "honorific prefix"@en ; rdfs:comment "The honorific prefix of the name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :honorific-suffix a owl:DatatypeProperty ; rdfs:label "honorific suffix"@en ; rdfs:comment "The honorific suffix of the name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :locality a owl:DatatypeProperty ; rdfs:label "locality"@en ; rdfs:comment "The locality (e.g. city or town) associated with the address of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :organization-name a owl:DatatypeProperty ; rdfs:label "organization name"@en ; rdfs:comment "To specify the organizational name associated with the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :postal-code a owl:DatatypeProperty ; rdfs:label "postal code"@en ; rdfs:comment "The postal code associated with the address of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :region a owl:DatatypeProperty ; rdfs:label "region"@en ; rdfs:comment "The region (e.g. state or province) associated with the address of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :street-address a owl:DatatypeProperty ; rdfs:label "street address"@en ; rdfs:comment "The street address associated with the address of the object"@en ; rdfs:isDefinedBy ; rdfs:range xsd:string . :Organization a owl:Class ; rdfs:label "Organization"@en ; rdfs:comment """An object representing an organization. An organization is a single entity, and might represent a business or government, a department or division within a business or government, a club, an association, or the like. """@en ; rdfs:isDefinedBy ; rdfs:subClassOf :Kind . :Gender a owl:Class ; rdfs:label "Gender"@en ; rdfs:comment "Used for gender codes. The URI of the gender code must be used as the value for Gender."@en ; rdfs:isDefinedBy . :Kind a owl:Class ; rdfs:label "Kind"@en ; rdfs:comment "The parent class for all objects"@en ; rdfs:isDefinedBy ; owl:equivalentClass [ a owl:Restriction ; owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onDataRange xsd:string ; owl:onProperty :fn ], :VCard . :Type a owl:Class ; rdfs:label "Type"@en ; rdfs:comment "Used for type codes. The URI of the type code must be used as the value for Type."@en ; rdfs:isDefinedBy . :TelephoneType a owl:Class ; rdfs:label "Phone"@en ; rdfs:comment "Used for telephone type codes. The URI of the telephone type code must be used as the value for the Telephone Type."@en ; rdfs:isDefinedBy . :RelatedType a owl:Class ; rdfs:label "Relation Type"@en ; rdfs:comment "Used for relation type codes. The URI of the relation type code must be used as the value for the Relation Type."@en ; rdfs:isDefinedBy . a owl:Ontology ; rdfs:label "Ontology for vCard"@en ; rdfs:comment "Ontology for vCard based on RFC6350"@en ; owl:versionInfo "Final"@en . `); /***/ }), /***/ "./node_modules/contacts-pane/webidControl.js": /*!****************************************************!*\ !*** ./node_modules/contacts-pane/webidControl.js ***! \****************************************************/ /*! exports provided: addWebIDToContacts, removeWebIDFromContacts, renderWedidControl */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addWebIDToContacts", function() { return addWebIDToContacts; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeWebIDFromContacts", function() { return removeWebIDFromContacts; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderWedidControl", function() { return renderWedidControl; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); // Render a control to record the webids we have for this agent /* eslint-disable multiline-ternary */ const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] // const buttons = UI.buttonsn no const widgets = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"] const utils = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const style = solid_ui__WEBPACK_IMPORTED_MODULE_0__["style"] const WEBID_NOUN = 'Solid ID' const GREEN_PLUS = solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_34653_green.svg' const DOWN_ARROW = solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_1369241.svg' const UP_ARROW = solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_1369237.svg' const webidPanelBackgroundColor = '#ffe6ff' // Logic async function addWebIDToContacts (person, webid, context) { if (!webid.startsWith('https:')) { /// @@ well we will have other protcols like DID throw new Error('Does not look like a webid, must start with https:') } console.log(`Adding to ${person} a ${WEBID_NOUN}: ${webid}.`) const kb = context.kb const vcardURLThing = kb.bnode() const insertables = [ $rdf.st(person, ns.vcard('url'), vcardURLThing, person.doc()), $rdf.st(vcardURLThing, ns.rdf('type'), ns.vcard('WebID'), person.doc()), $rdf.st(vcardURLThing, ns.vcard('value'), webid, person.doc()) ] await kb.updater.update([], insertables) } async function removeWebIDFromContacts (person, webid, context) { const { kb } = context console.log(`Removing from ${person} their ${WEBID_NOUN}: ${webid}.`) const existing = kb.each(person, ns.vcard('url'), null, person.doc()) .filter(urlObject => kb.holds(urlObject, ns.rdf('type'), ns.vcard('WebID'), person.doc())) .filter(urlObject => kb.holds(urlObject, ns.vcard('value'), webid, person.doc())) if (!existing.length) { throw new Error(`Person ${person} does not have ${WEBID_NOUN} ${webid}.`) } const vcardURLThing = existing[0] const deletables = [ $rdf.st(person, ns.vcard('url'), vcardURLThing, person.doc()), $rdf.st(vcardURLThing, ns.rdf('type'), ns.vcard('WebID'), person.doc()), $rdf.st(vcardURLThing, ns.vcard('value'), webid, person.doc()) ] await kb.updater.update(deletables, []) } // The control rendered by this module async function renderWedidControl (person, dataBrowserContext) { // IDs which are as WebId in VCARD data // like :me vcard:hasURL [ a vcard:WebId; vcard:value ] // function vcardWebIDs (person) { return kb.each(person, ns.vcard('url'), null, person.doc()) .filter(urlObject => kb.holds(urlObject, ns.rdf('type'), ns.vcard('WebID'), person.doc())) .map(urlObject => kb.any(urlObject, ns.vcard('value'), null, person.doc())) .filter(x => !!x) // remove nulls } function _getAliases (person) { return kb.allAliases(person) // All the terms linked by sameAs .filter(x => !x.sameTerm(person)) // Except this one } // Trace things the same as this - other IDs for same thing // returns as array of node function getSameAs (thing, doc) { // Should this recurse? const found = new Set() const agenda = new Set([thing.uri]) while (agenda.size) { const uri = Array.from(agenda)[0] // clumsy agenda.delete(uri) if (found.has(uri)) continue found.add(uri) const node = kb.sym(uri) kb.each(node, ns.owl('sameAs'), null, doc) .concat(kb.each(null, ns.owl('sameAs'), node, doc)) .forEach(next => { console.log(' OWL sameAs found ' + next) agenda.add(next.uri) }) kb.each(node, ns.schema('sameAs'), null, doc) .concat(kb.each(null, ns.schema('sameAs'), node, doc)) .forEach(next => { console.log(' Schema sameAs found ' + next) agenda.add(next.uri) }) } found.delete(thing.uri) // don't want the one we knew about return Array.from(found).map(uri => kb.sym(uri)) // return as array of nodes } function renderNewRow (webidObject) { const webid = new $rdf.Literal(webidObject.uri) async function deleteFunction () { try { await removeWebIDFromContacts(person, webid, { kb }) } catch (err) { div.appendChild(widgets.errorMessageBlock(dom, err)) } await refreshWebIDTable() } const delFunParam = editable ? deleteFunction : null const title = webidObject.uri.split('/')[2] // domain name const image = widgets.faviconOrDefault(dom, webidObject.site()) // image just for domain const options = { deleteFunction: delFunParam, draggable: true, title, image } const row = widgets.personTR(dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].foaf('knows'), webidObject, options) // const row = UI.widgets.personTR(dom, UI.ns.foaf('knows'), webidObject, options) row.children[1].textConent = title // @@ will be overwritten row.style.backgroundColor = webidPanelBackgroundColor row.style.padding = '0.2em' return row } function _renderNewRow2 (x) { // alternative const tr = table.appendChild(dom.createElement('tr')) tr.setAttribute('style', 'margin-top: 0.1em solid #ccc;') const nameTD = tr.appendChild(dom.createElement('td')) const formTD = tr.appendChild(dom.createElement('td')) nameTD.textContent = x.uri.split('/')[2] // domain part kb.fetcher // Load the profile .load(x.doc()) .then(function (_xhr) { nameTD.textContent = x.uri.split('/')[2] + ' (' + kb.statementsMatching( undefined, undefined, undefined, x.doc() ).length + ')' }) .catch(function (e) { formTD.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, e, 'pink')) }) return tr } function renderPane (dom, subject, paneName) { const p = dataBrowserContext.session.paneRegistry.byName(paneName) const d = p.render(subject, dataBrowserContext) // @@@ change some bits of context! d.setAttribute( 'style', 'border: 0.1em solid #444; border-radius: 0.5em' ) return d } function getPersonas () { const lits = vcardWebIDs(person).concat(getSameAs(person, person.doc())) const strings = new Set(lits.map(lit => lit.value)) // remove dups const personas = [...strings].map(uri => kb.sym(uri)) // The UI tables do better with Named Nodes than Literals personas.sort() // for repeatability personas.filter(x => !x.sameTerm(person)) return personas } function _renderPersona (persona) { function profileOpenHandler (_event) { profileIsVisible = !profileIsVisible main.style.visibility = profileIsVisible ? 'visible' : 'collapse' openButton.children[0].src = profileIsVisible ? UP_ARROW : DOWN_ARROW // @@ fragile } const div = dom.createElement('div') const nav = div.appendChild(dom.createElement('nav')) nav.style = style.personaBarStyle const title = persona.uri // .split('/')[2] // domain name let main const header = nav.appendChild(dom.createElement('span')) header.textContent = title let profileIsVisible = false const openButton = nav.appendChild(widgets.button(dom, DOWN_ARROW, 'View', profileOpenHandler)) openButton.style.float = 'right' delete openButton.style.backgroundColor delete openButton.style.border kb.fetcher.load(persona).then(_resp => { try { main = div.appendChild(renderPane(dom, persona, 'profile')) main.style.visibility = 'collapse' } catch (err) { main = widgets.errorMessageBlock(dom, `Error loading persona ${persona}: ${err}`) } }, err => { main = widgets.errorMessageBlock(dom, `Problem displaying persona ${persona}: ${err}`) }) return div } // renderPersona function renderPersona2 (persona) { function profileOpenHandler (_event) { profileIsVisible = !profileIsVisible main.style.visibility = profileIsVisible ? 'visible' : 'collapse' openButton.children[0].src = profileIsVisible ? UP_ARROW : DOWN_ARROW // @@ fragile } const div = dom.createElement('div') div.style.width = '100%' const personaTable = div.appendChild(dom.createElement('table')) personaTable.style.width = '100%' const nav = personaTable.appendChild(renderNewRow(persona)) nav.style.width = '100%' const mainRow = personaTable.appendChild(dom.createElement('tr')) const mainCell = mainRow.appendChild(dom.createElement('td')) mainCell.setAttribute('colspan', 3) let main let profileIsVisible = true const rhs = nav.children[2] const openButton = rhs.appendChild(widgets.button(dom, DOWN_ARROW, 'View', profileOpenHandler)) openButton.style.float = 'right' delete openButton.style.backgroundColor delete openButton.style.border kb.fetcher.load(persona).then(_resp => { try { main = renderPane(dom, persona, 'profile') main.style.width = '100%' // main.style.visibility = 'collapse' mainCell.appendChild(main) } catch (err) { main = widgets.errorMessageBlock(dom, `Problem displaying persona ${persona}: ${err}`) mainCell.appendChild(main) } }, err => { main = widgets.errorMessageBlock(dom, `Error loading persona ${persona}: ${err}`) mainCell.appendChild(main) }) return div } // renderPersona2 async function refreshWebIDTable () { const personas = getPersonas() console.log('WebId personas: ' + person + ' -> ' + personas.map(p => p.uri).join(',\n ')) prompt.style.display = personas.length ? 'none' : '' // utils.syncTableToArrayReOrdered(table, personas, renderNewRow) utils.syncTableToArrayReOrdered(profileArea, personas, renderPersona2) } async function greenButtonHandler (_event) { const webid = await solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].askName(dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"], div, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].vcard('url'), null, WEBID_NOUN) if (!webid) { return // cancelled by user } try { await addWebIDToContacts(person, webid, { kb: kb }) } catch (err) { div.appendChild(widgets.errorMessageBlock(dom, err)) } await refreshWebIDTable() } async function droppedURIHandler (uris) { for (const webid of uris) { try { await addWebIDToContacts(person, webid, { kb: kb }) } catch (err) { div.appendChild(widgets.errorMessageBlock(dom, err)) } } await refreshWebIDTable() } const { dom } = dataBrowserContext const editable = kb.updater.editable(person.doc().uri, kb) const div = dom.createElement('div') div.style = 'border-radius:0.3em; border: 0.1em solid #888;' // padding: 0.8em; if (getPersonas().length === 0 && !editable) { div.style.display = 'none' return div // No point listing an empty list you can't change } const h4 = div.appendChild(dom.createElement('h4')) h4.textContent = WEBID_NOUN h4.style = style.formHeadingStyle h4.style.color = style.highlightColor const prompt = div.appendChild(dom.createElement('p')) prompt.style = style.commentStyle prompt.textContent = `If you know someone's ${WEBID_NOUN}, you can do more stuff with them. To record their ${WEBID_NOUN}, drag it onto the plus, or click the plus to bring up a selector.` const table = div.appendChild(dom.createElement('table')) table.style.width = '100%' if (editable) { const plus = div.appendChild(widgets.button(dom, GREEN_PLUS, WEBID_NOUN, greenButtonHandler)) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDropTarget(plus, droppedURIHandler, null) } const profileArea = div.appendChild(dom.createElement('div')) await refreshWebIDTable() return div } /***/ }), /***/ "./node_modules/cross-fetch/dist/browser-ponyfill.js": /*!***********************************************************!*\ !*** ./node_modules/cross-fetch/dist/browser-ponyfill.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports) { var __self__ = (function (root) { function F() { this.fetch = false; this.DOMException = root.DOMException } F.prototype = root; return new F(); })(typeof self !== 'undefined' ? self : this); (function(self) { var irrelevant = (function (exports) { var support = { searchParams: 'URLSearchParams' in self, iterable: 'Symbol' in self && 'iterator' in Symbol, blob: 'FileReader' in self && 'Blob' in self && (function() { try { new Blob(); return true } catch (e) { return false } })(), formData: 'FormData' in self, arrayBuffer: 'ArrayBuffer' in self }; function isDataView(obj) { return obj && DataView.prototype.isPrototypeOf(obj) } if (support.arrayBuffer) { var viewClasses = [ '[object Int8Array]', '[object Uint8Array]', '[object Uint8ClampedArray]', '[object Int16Array]', '[object Uint16Array]', '[object Int32Array]', '[object Uint32Array]', '[object Float32Array]', '[object Float64Array]' ]; var isArrayBufferView = ArrayBuffer.isView || function(obj) { return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 }; } function normalizeName(name) { if (typeof name !== 'string') { name = String(name); } if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) { throw new TypeError('Invalid character in header field name') } return name.toLowerCase() } function normalizeValue(value) { if (typeof value !== 'string') { value = String(value); } return value } // Build a destructive iterator for the value list function iteratorFor(items) { var iterator = { next: function() { var value = items.shift(); return {done: value === undefined, value: value} } }; if (support.iterable) { iterator[Symbol.iterator] = function() { return iterator }; } return iterator } function Headers(headers) { this.map = {}; if (headers instanceof Headers) { headers.forEach(function(value, name) { this.append(name, value); }, this); } else if (Array.isArray(headers)) { headers.forEach(function(header) { this.append(header[0], header[1]); }, this); } else if (headers) { Object.getOwnPropertyNames(headers).forEach(function(name) { this.append(name, headers[name]); }, this); } } Headers.prototype.append = function(name, value) { name = normalizeName(name); value = normalizeValue(value); var oldValue = this.map[name]; this.map[name] = oldValue ? oldValue + ', ' + value : value; }; Headers.prototype['delete'] = function(name) { delete this.map[normalizeName(name)]; }; Headers.prototype.get = function(name) { name = normalizeName(name); return this.has(name) ? this.map[name] : null }; Headers.prototype.has = function(name) { return this.map.hasOwnProperty(normalizeName(name)) }; Headers.prototype.set = function(name, value) { this.map[normalizeName(name)] = normalizeValue(value); }; Headers.prototype.forEach = function(callback, thisArg) { for (var name in this.map) { if (this.map.hasOwnProperty(name)) { callback.call(thisArg, this.map[name], name, this); } } }; Headers.prototype.keys = function() { var items = []; this.forEach(function(value, name) { items.push(name); }); return iteratorFor(items) }; Headers.prototype.values = function() { var items = []; this.forEach(function(value) { items.push(value); }); return iteratorFor(items) }; Headers.prototype.entries = function() { var items = []; this.forEach(function(value, name) { items.push([name, value]); }); return iteratorFor(items) }; if (support.iterable) { Headers.prototype[Symbol.iterator] = Headers.prototype.entries; } function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) } body.bodyUsed = true; } function fileReaderReady(reader) { return new Promise(function(resolve, reject) { reader.onload = function() { resolve(reader.result); }; reader.onerror = function() { reject(reader.error); }; }) } function readBlobAsArrayBuffer(blob) { var reader = new FileReader(); var promise = fileReaderReady(reader); reader.readAsArrayBuffer(blob); return promise } function readBlobAsText(blob) { var reader = new FileReader(); var promise = fileReaderReady(reader); reader.readAsText(blob); return promise } function readArrayBufferAsText(buf) { var view = new Uint8Array(buf); var chars = new Array(view.length); for (var i = 0; i < view.length; i++) { chars[i] = String.fromCharCode(view[i]); } return chars.join('') } function bufferClone(buf) { if (buf.slice) { return buf.slice(0) } else { var view = new Uint8Array(buf.byteLength); view.set(new Uint8Array(buf)); return view.buffer } } function Body() { this.bodyUsed = false; this._initBody = function(body) { this._bodyInit = body; if (!body) { this._bodyText = ''; } else if (typeof body === 'string') { this._bodyText = body; } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { this._bodyBlob = body; } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { this._bodyFormData = body; } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this._bodyText = body.toString(); } else if (support.arrayBuffer && support.blob && isDataView(body)) { this._bodyArrayBuffer = bufferClone(body.buffer); // IE 10-11 can't handle a DataView body. this._bodyInit = new Blob([this._bodyArrayBuffer]); } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { this._bodyArrayBuffer = bufferClone(body); } else { this._bodyText = body = Object.prototype.toString.call(body); } if (!this.headers.get('content-type')) { if (typeof body === 'string') { this.headers.set('content-type', 'text/plain;charset=UTF-8'); } else if (this._bodyBlob && this._bodyBlob.type) { this.headers.set('content-type', this._bodyBlob.type); } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); } } }; if (support.blob) { this.blob = function() { var rejected = consumed(this); if (rejected) { return rejected } if (this._bodyBlob) { return Promise.resolve(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(new Blob([this._bodyArrayBuffer])) } else if (this._bodyFormData) { throw new Error('could not read FormData body as blob') } else { return Promise.resolve(new Blob([this._bodyText])) } }; this.arrayBuffer = function() { if (this._bodyArrayBuffer) { return consumed(this) || Promise.resolve(this._bodyArrayBuffer) } else { return this.blob().then(readBlobAsArrayBuffer) } }; } this.text = function() { var rejected = consumed(this); if (rejected) { return rejected } if (this._bodyBlob) { return readBlobAsText(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) } else if (this._bodyFormData) { throw new Error('could not read FormData body as text') } else { return Promise.resolve(this._bodyText) } }; if (support.formData) { this.formData = function() { return this.text().then(decode) }; } this.json = function() { return this.text().then(JSON.parse) }; return this } // HTTP methods whose capitalization should be normalized var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; function normalizeMethod(method) { var upcased = method.toUpperCase(); return methods.indexOf(upcased) > -1 ? upcased : method } function Request(input, options) { options = options || {}; var body = options.body; if (input instanceof Request) { if (input.bodyUsed) { throw new TypeError('Already read') } this.url = input.url; this.credentials = input.credentials; if (!options.headers) { this.headers = new Headers(input.headers); } this.method = input.method; this.mode = input.mode; this.signal = input.signal; if (!body && input._bodyInit != null) { body = input._bodyInit; input.bodyUsed = true; } } else { this.url = String(input); } this.credentials = options.credentials || this.credentials || 'same-origin'; if (options.headers || !this.headers) { this.headers = new Headers(options.headers); } this.method = normalizeMethod(options.method || this.method || 'GET'); this.mode = options.mode || this.mode || null; this.signal = options.signal || this.signal; this.referrer = null; if ((this.method === 'GET' || this.method === 'HEAD') && body) { throw new TypeError('Body not allowed for GET or HEAD requests') } this._initBody(body); } Request.prototype.clone = function() { return new Request(this, {body: this._bodyInit}) }; function decode(body) { var form = new FormData(); body .trim() .split('&') .forEach(function(bytes) { if (bytes) { var split = bytes.split('='); var name = split.shift().replace(/\+/g, ' '); var value = split.join('=').replace(/\+/g, ' '); form.append(decodeURIComponent(name), decodeURIComponent(value)); } }); return form } function parseHeaders(rawHeaders) { var headers = new Headers(); // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space // https://tools.ietf.org/html/rfc7230#section-3.2 var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); preProcessedHeaders.split(/\r?\n/).forEach(function(line) { var parts = line.split(':'); var key = parts.shift().trim(); if (key) { var value = parts.join(':').trim(); headers.append(key, value); } }); return headers } Body.call(Request.prototype); function Response(bodyInit, options) { if (!options) { options = {}; } this.type = 'default'; this.status = options.status === undefined ? 200 : options.status; this.ok = this.status >= 200 && this.status < 300; this.statusText = 'statusText' in options ? options.statusText : 'OK'; this.headers = new Headers(options.headers); this.url = options.url || ''; this._initBody(bodyInit); } Body.call(Response.prototype); Response.prototype.clone = function() { return new Response(this._bodyInit, { status: this.status, statusText: this.statusText, headers: new Headers(this.headers), url: this.url }) }; Response.error = function() { var response = new Response(null, {status: 0, statusText: ''}); response.type = 'error'; return response }; var redirectStatuses = [301, 302, 303, 307, 308]; Response.redirect = function(url, status) { if (redirectStatuses.indexOf(status) === -1) { throw new RangeError('Invalid status code') } return new Response(null, {status: status, headers: {location: url}}) }; exports.DOMException = self.DOMException; try { new exports.DOMException(); } catch (err) { exports.DOMException = function(message, name) { this.message = message; this.name = name; var error = Error(message); this.stack = error.stack; }; exports.DOMException.prototype = Object.create(Error.prototype); exports.DOMException.prototype.constructor = exports.DOMException; } function fetch(input, init) { return new Promise(function(resolve, reject) { var request = new Request(input, init); if (request.signal && request.signal.aborted) { return reject(new exports.DOMException('Aborted', 'AbortError')) } var xhr = new XMLHttpRequest(); function abortXhr() { xhr.abort(); } xhr.onload = function() { var options = { status: xhr.status, statusText: xhr.statusText, headers: parseHeaders(xhr.getAllResponseHeaders() || '') }; options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); var body = 'response' in xhr ? xhr.response : xhr.responseText; resolve(new Response(body, options)); }; xhr.onerror = function() { reject(new TypeError('Network request failed')); }; xhr.ontimeout = function() { reject(new TypeError('Network request failed')); }; xhr.onabort = function() { reject(new exports.DOMException('Aborted', 'AbortError')); }; xhr.open(request.method, request.url, true); if (request.credentials === 'include') { xhr.withCredentials = true; } else if (request.credentials === 'omit') { xhr.withCredentials = false; } if ('responseType' in xhr && support.blob) { xhr.responseType = 'blob'; } request.headers.forEach(function(value, name) { xhr.setRequestHeader(name, value); }); if (request.signal) { request.signal.addEventListener('abort', abortXhr); xhr.onreadystatechange = function() { // DONE (success or failure) if (xhr.readyState === 4) { request.signal.removeEventListener('abort', abortXhr); } }; } xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit); }) } fetch.polyfill = true; if (!self.fetch) { self.fetch = fetch; self.Headers = Headers; self.Request = Request; self.Response = Response; } exports.Headers = Headers; exports.Request = Request; exports.Response = Response; exports.fetch = fetch; return exports; }({})); })(__self__); delete __self__.fetch.polyfill exports = __self__.fetch // To enable: import fetch from 'cross-fetch' exports.default = __self__.fetch // For TypeScript consumers without esModuleInterop. exports.fetch = __self__.fetch // To enable: import {fetch} from 'cross-fetch' exports.Headers = __self__.Headers exports.Request = __self__.Request exports.Response = __self__.Response module.exports = exports /***/ }), /***/ "./node_modules/css-jss/dist/css-jss.esm.js": /*!**************************************************!*\ !*** ./node_modules/css-jss/dist/css-jss.esm.js ***! \**************************************************/ /*! exports provided: default, create */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "create", function() { return createCss; }); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); /* harmony import */ var jss_preset_default__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss-preset-default */ "./node_modules/jss-preset-default/dist/jss-preset-default.esm.js"); // I have been trying to benchmark and I have seen a slow down after about 10k rules. // Since we are in a single sheet mode, user shouldn't care about this. var MAX_RULES_PER_SHEET = 10000; var defaultJss = Object(jss__WEBPACK_IMPORTED_MODULE_0__["create"])(Object(jss_preset_default__WEBPACK_IMPORTED_MODULE_1__["default"])()); var createCss = function createCss(jss) { if (jss === void 0) { jss = defaultJss; } var cache = new Map(); var ruleIndex = 0; var sheet; var getSheet = function getSheet() { if (!sheet || sheet.rules.index.length > MAX_RULES_PER_SHEET) { sheet = jss.createStyleSheet().attach(); } return sheet; }; function css() { // eslint-disable-next-line prefer-rest-params var args = arguments; // We can avoid the need for stringification with a babel plugin, // which could generate a hash at build time and add it to the object. var argsStr = JSON.stringify(args); var cached = cache.get(argsStr); if (cached) return cached.className; var flatArgs = []; // Flatten arguments which can be // - style objects // - array of style objects // - arrays of style objects for (var argIndex in args) { var arg = args[argIndex]; if (!Array.isArray(arg)) { flatArgs.push(arg); continue; } for (var innerArgIndex = 0; innerArgIndex < arg.length; innerArgIndex++) { flatArgs.push(arg[innerArgIndex]); } } var mergedStyle = {}; var labels = []; for (var i = 0; i < flatArgs.length; i++) { var style = flatArgs[i]; if (!style) continue; var styleObject = style; // It can be a class name that css() has previously generated. if (typeof style === 'string') { // eslint-disable-next-line no-shadow var _cached = cache.get(style); if (_cached) { // eslint-disable-next-line prefer-spread if (_cached.labels.length) labels.push.apply(labels, _cached.labels); styleObject = _cached.style; } } if (styleObject.label && labels.indexOf(styleObject.label) === -1) labels.push(styleObject.label); Object.assign(mergedStyle, styleObject); } delete mergedStyle.label; var label = labels.length === 0 ? 'css' : labels.join('-'); var key = label + "-" + ruleIndex++; getSheet().addRule(key, mergedStyle); var className = getSheet().classes[key]; var cacheValue = { style: mergedStyle, labels: labels, className: className }; cache.set(argsStr, cacheValue); cache.set(className, cacheValue); return className; } // For testing only. css.getSheet = getSheet; return css; }; var css = createCss(); /* harmony default export */ __webpack_exports__["default"] = (css); /***/ }), /***/ "./node_modules/css-vendor/dist/css-vendor.esm.js": /*!********************************************************!*\ !*** ./node_modules/css-vendor/dist/css-vendor.esm.js ***! \********************************************************/ /*! exports provided: prefix, supportedKeyframes, supportedProperty, supportedValue */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prefix", function() { return prefix; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedKeyframes", function() { return supportedKeyframes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedProperty", function() { return supportedProperty; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedValue", function() { return supportedValue; }); /* harmony import */ var is_in_browser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! is-in-browser */ "./node_modules/is-in-browser/dist/module.js"); /* harmony import */ var _babel_runtime_helpers_esm_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/esm/toConsumableArray */ "./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js"); // Export javascript style and css style vendor prefixes. var js = ''; var css = ''; var vendor = ''; var browser = ''; var isTouch = is_in_browser__WEBPACK_IMPORTED_MODULE_0__["default"] && 'ontouchstart' in document.documentElement; // We should not do anything if required serverside. if (is_in_browser__WEBPACK_IMPORTED_MODULE_0__["default"]) { // Order matters. We need to check Webkit the last one because // other vendors use to add Webkit prefixes to some properties var jsCssMap = { Moz: '-moz-', ms: '-ms-', O: '-o-', Webkit: '-webkit-' }; var _document$createEleme = document.createElement('p'), style = _document$createEleme.style; var testProp = 'Transform'; for (var key in jsCssMap) { if (key + testProp in style) { js = key; css = jsCssMap[key]; break; } } // Correctly detect the Edge browser. if (js === 'Webkit' && 'msHyphens' in style) { js = 'ms'; css = jsCssMap.ms; browser = 'edge'; } // Correctly detect the Safari browser. if (js === 'Webkit' && '-apple-trailing-word' in style) { vendor = 'apple'; } } /** * Vendor prefix string for the current browser. * * @type {{js: String, css: String, vendor: String, browser: String}} * @api public */ var prefix = { js: js, css: css, vendor: vendor, browser: browser, isTouch: isTouch }; /** * Test if a keyframe at-rule should be prefixed or not * * @param {String} vendor prefix string for the current browser. * @return {String} * @api public */ function supportedKeyframes(key) { // Keyframes is already prefixed. e.g. key = '@-webkit-keyframes a' if (key[1] === '-') return key; // No need to prefix IE/Edge. Older browsers will ignore unsupported rules. // https://caniuse.com/#search=keyframes if (prefix.js === 'ms') return key; return "@" + prefix.css + "keyframes" + key.substr(10); } // https://caniuse.com/#search=appearance var appearence = { noPrefill: ['appearance'], supportedProperty: function supportedProperty(prop) { if (prop !== 'appearance') return false; if (prefix.js === 'ms') return "-webkit-" + prop; return prefix.css + prop; } }; // https://caniuse.com/#search=color-adjust var colorAdjust = { noPrefill: ['color-adjust'], supportedProperty: function supportedProperty(prop) { if (prop !== 'color-adjust') return false; if (prefix.js === 'Webkit') return prefix.css + "print-" + prop; return prop; } }; var regExp = /[-\s]+(.)?/g; /** * Replaces the letter with the capital letter * * @param {String} match * @param {String} c * @return {String} * @api private */ function toUpper(match, c) { return c ? c.toUpperCase() : ''; } /** * Convert dash separated strings to camel-cased. * * @param {String} str * @return {String} * @api private */ function camelize(str) { return str.replace(regExp, toUpper); } /** * Convert dash separated strings to pascal cased. * * @param {String} str * @return {String} * @api private */ function pascalize(str) { return camelize("-" + str); } // but we can use a longhand property instead. // https://caniuse.com/#search=mask var mask = { noPrefill: ['mask'], supportedProperty: function supportedProperty(prop, style) { if (!/^mask/.test(prop)) return false; if (prefix.js === 'Webkit') { var longhand = 'mask-image'; if (camelize(longhand) in style) { return prop; } if (prefix.js + pascalize(longhand) in style) { return prefix.css + prop; } } return prop; } }; // https://caniuse.com/#search=text-orientation var textOrientation = { noPrefill: ['text-orientation'], supportedProperty: function supportedProperty(prop) { if (prop !== 'text-orientation') return false; if (prefix.vendor === 'apple' && !prefix.isTouch) { return prefix.css + prop; } return prop; } }; // https://caniuse.com/#search=transform var transform = { noPrefill: ['transform'], supportedProperty: function supportedProperty(prop, style, options) { if (prop !== 'transform') return false; if (options.transform) { return prop; } return prefix.css + prop; } }; // https://caniuse.com/#search=transition var transition = { noPrefill: ['transition'], supportedProperty: function supportedProperty(prop, style, options) { if (prop !== 'transition') return false; if (options.transition) { return prop; } return prefix.css + prop; } }; // https://caniuse.com/#search=writing-mode var writingMode = { noPrefill: ['writing-mode'], supportedProperty: function supportedProperty(prop) { if (prop !== 'writing-mode') return false; if (prefix.js === 'Webkit' || prefix.js === 'ms' && prefix.browser !== 'edge') { return prefix.css + prop; } return prop; } }; // https://caniuse.com/#search=user-select var userSelect = { noPrefill: ['user-select'], supportedProperty: function supportedProperty(prop) { if (prop !== 'user-select') return false; if (prefix.js === 'Moz' || prefix.js === 'ms' || prefix.vendor === 'apple') { return prefix.css + prop; } return prop; } }; // https://caniuse.com/#search=multicolumn // https://github.com/postcss/autoprefixer/issues/491 // https://github.com/postcss/autoprefixer/issues/177 var breakPropsOld = { supportedProperty: function supportedProperty(prop, style) { if (!/^break-/.test(prop)) return false; if (prefix.js === 'Webkit') { var jsProp = "WebkitColumn" + pascalize(prop); return jsProp in style ? prefix.css + "column-" + prop : false; } if (prefix.js === 'Moz') { var _jsProp = "page" + pascalize(prop); return _jsProp in style ? "page-" + prop : false; } return false; } }; // See https://github.com/postcss/autoprefixer/issues/324. var inlineLogicalOld = { supportedProperty: function supportedProperty(prop, style) { if (!/^(border|margin|padding)-inline/.test(prop)) return false; if (prefix.js === 'Moz') return prop; var newProp = prop.replace('-inline', ''); return prefix.js + pascalize(newProp) in style ? prefix.css + newProp : false; } }; // Camelization is required because we can't test using. // CSS syntax for e.g. in FF. var unprefixed = { supportedProperty: function supportedProperty(prop, style) { return camelize(prop) in style ? prop : false; } }; var prefixed = { supportedProperty: function supportedProperty(prop, style) { var pascalized = pascalize(prop); // Return custom CSS variable without prefixing. if (prop[0] === '-') return prop; // Return already prefixed value without prefixing. if (prop[0] === '-' && prop[1] === '-') return prop; if (prefix.js + pascalized in style) return prefix.css + prop; // Try webkit fallback. if (prefix.js !== 'Webkit' && "Webkit" + pascalized in style) return "-webkit-" + prop; return false; } }; // https://caniuse.com/#search=scroll-snap var scrollSnap = { supportedProperty: function supportedProperty(prop) { if (prop.substring(0, 11) !== 'scroll-snap') return false; if (prefix.js === 'ms') { return "" + prefix.css + prop; } return prop; } }; // https://caniuse.com/#search=overscroll-behavior var overscrollBehavior = { supportedProperty: function supportedProperty(prop) { if (prop !== 'overscroll-behavior') return false; if (prefix.js === 'ms') { return prefix.css + "scroll-chaining"; } return prop; } }; var propMap = { 'flex-grow': 'flex-positive', 'flex-shrink': 'flex-negative', 'flex-basis': 'flex-preferred-size', 'justify-content': 'flex-pack', order: 'flex-order', 'align-items': 'flex-align', 'align-content': 'flex-line-pack' // 'align-self' is handled by 'align-self' plugin. }; // Support old flex spec from 2012. var flex2012 = { supportedProperty: function supportedProperty(prop, style) { var newProp = propMap[prop]; if (!newProp) return false; return prefix.js + pascalize(newProp) in style ? prefix.css + newProp : false; } }; var propMap$1 = { flex: 'box-flex', 'flex-grow': 'box-flex', 'flex-direction': ['box-orient', 'box-direction'], order: 'box-ordinal-group', 'align-items': 'box-align', 'flex-flow': ['box-orient', 'box-direction'], 'justify-content': 'box-pack' }; var propKeys = Object.keys(propMap$1); var prefixCss = function prefixCss(p) { return prefix.css + p; }; // Support old flex spec from 2009. var flex2009 = { supportedProperty: function supportedProperty(prop, style, _ref) { var multiple = _ref.multiple; if (propKeys.indexOf(prop) > -1) { var newProp = propMap$1[prop]; if (!Array.isArray(newProp)) { return prefix.js + pascalize(newProp) in style ? prefix.css + newProp : false; } if (!multiple) return false; for (var i = 0; i < newProp.length; i++) { if (!(prefix.js + pascalize(newProp[0]) in style)) { return false; } } return newProp.map(prefixCss); } return false; } }; // plugins = [ // ...plugins, // breakPropsOld, // inlineLogicalOld, // unprefixed, // prefixed, // scrollSnap, // flex2012, // flex2009 // ] // Plugins without 'noPrefill' value, going last. // 'flex-*' plugins should be at the bottom. // 'flex2009' going after 'flex2012'. // 'prefixed' going after 'unprefixed' var plugins = [appearence, colorAdjust, mask, textOrientation, transform, transition, writingMode, userSelect, breakPropsOld, inlineLogicalOld, unprefixed, prefixed, scrollSnap, overscrollBehavior, flex2012, flex2009]; var propertyDetectors = plugins.filter(function (p) { return p.supportedProperty; }).map(function (p) { return p.supportedProperty; }); var noPrefill = plugins.filter(function (p) { return p.noPrefill; }).reduce(function (a, p) { a.push.apply(a, Object(_babel_runtime_helpers_esm_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__["default"])(p.noPrefill)); return a; }, []); var el; var cache = {}; if (is_in_browser__WEBPACK_IMPORTED_MODULE_0__["default"]) { el = document.createElement('p'); // We test every property on vendor prefix requirement. // Once tested, result is cached. It gives us up to 70% perf boost. // http://jsperf.com/element-style-object-access-vs-plain-object // // Prefill cache with known css properties to reduce amount of // properties we need to feature test at runtime. // http://davidwalsh.name/vendor-prefix var computed = window.getComputedStyle(document.documentElement, ''); for (var key$1 in computed) { // eslint-disable-next-line no-restricted-globals if (!isNaN(key$1)) cache[computed[key$1]] = computed[key$1]; } // Properties that cannot be correctly detected using the // cache prefill method. noPrefill.forEach(function (x) { return delete cache[x]; }); } /** * Test if a property is supported, returns supported property with vendor * prefix if required. Returns `false` if not supported. * * @param {String} prop dash separated * @param {Object} [options] * @return {String|Boolean} * @api public */ function supportedProperty(prop, options) { if (options === void 0) { options = {}; } // For server-side rendering. if (!el) return prop; // Remove cache for benchmark tests or return property from the cache. if ( true && cache[prop] != null) { return cache[prop]; } // Check if 'transition' or 'transform' natively supported in browser. if (prop === 'transition' || prop === 'transform') { options[prop] = prop in el.style; } // Find a plugin for current prefix property. for (var i = 0; i < propertyDetectors.length; i++) { cache[prop] = propertyDetectors[i](prop, el.style, options); // Break loop, if value found. if (cache[prop]) break; } // Reset styles for current property. // Firefox can even throw an error for invalid properties, e.g., "0". try { el.style[prop] = ''; } catch (err) { return false; } return cache[prop]; } var cache$1 = {}; var transitionProperties = { transition: 1, 'transition-property': 1, '-webkit-transition': 1, '-webkit-transition-property': 1 }; var transPropsRegExp = /(^\s*[\w-]+)|, (\s*[\w-]+)(?![^()]*\))/g; var el$1; /** * Returns prefixed value transition/transform if needed. * * @param {String} match * @param {String} p1 * @param {String} p2 * @return {String} * @api private */ function prefixTransitionCallback(match, p1, p2) { if (p1 === 'var') return 'var'; if (p1 === 'all') return 'all'; if (p2 === 'all') return ', all'; var prefixedValue = p1 ? supportedProperty(p1) : ", " + supportedProperty(p2); if (!prefixedValue) return p1 || p2; return prefixedValue; } if (is_in_browser__WEBPACK_IMPORTED_MODULE_0__["default"]) el$1 = document.createElement('p'); /** * Returns prefixed value if needed. Returns `false` if value is not supported. * * @param {String} property * @param {String} value * @return {String|Boolean} * @api public */ function supportedValue(property, value) { // For server-side rendering. var prefixedValue = value; if (!el$1 || property === 'content') return value; // It is a string or a number as a string like '1'. // We want only prefixable values here. // eslint-disable-next-line no-restricted-globals if (typeof prefixedValue !== 'string' || !isNaN(parseInt(prefixedValue, 10))) { return prefixedValue; } // Create cache key for current value. var cacheKey = property + prefixedValue; // Remove cache for benchmark tests or return value from cache. if ( true && cache$1[cacheKey] != null) { return cache$1[cacheKey]; } // IE can even throw an error in some cases, for e.g. style.content = 'bar'. try { // Test value as it is. el$1.style[property] = prefixedValue; } catch (err) { // Return false if value not supported. cache$1[cacheKey] = false; return false; } // If 'transition' or 'transition-property' property. if (transitionProperties[property]) { prefixedValue = prefixedValue.replace(transPropsRegExp, prefixTransitionCallback); } else if (el$1.style[property] === '') { // Value with a vendor prefix. prefixedValue = prefix.css + prefixedValue; // Hardcode test to convert "flex" to "-ms-flexbox" for IE10. if (prefixedValue === '-ms-flex') el$1.style[property] = '-ms-flexbox'; // Test prefixed value. el$1.style[property] = prefixedValue; // Return false if value not supported. if (el$1.style[property] === '') { cache$1[cacheKey] = false; return false; } } // Reset styles for current property. el$1.style[property] = ''; // Write current value to cache. cache$1[cacheKey] = prefixedValue; return cache$1[cacheKey]; } /***/ }), /***/ "./node_modules/escape-html/index.js": /*!*******************************************!*\ !*** ./node_modules/escape-html/index.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! * escape-html * Copyright(c) 2012-2013 TJ Holowaychuk * Copyright(c) 2015 Andreas Lubbe * Copyright(c) 2015 Tiancheng "Timothy" Gu * MIT Licensed */ /** * Module variables. * @private */ var matchHtmlRegExp = /["'&<>]/; /** * Module exports. * @public */ module.exports = escapeHtml; /** * Escape special characters in the given string of html. * * @param {string} string The string to escape for inserting into HTML * @return {string} * @public */ function escapeHtml(string) { var str = '' + string; var match = matchHtmlRegExp.exec(str); if (!match) { return str; } var escape; var html = ''; var index = 0; var lastIndex = 0; for (index = match.index; index < str.length; index++) { switch (str.charCodeAt(index)) { case 34: // " escape = '"'; break; case 38: // & escape = '&'; break; case 39: // ' escape = '''; break; case 60: // < escape = '<'; break; case 62: // > escape = '>'; break; default: continue; } if (lastIndex !== index) { html += str.substring(lastIndex, index); } lastIndex = index + 1; html += escape; } return lastIndex !== index ? html + str.substring(lastIndex, index) : html; } /***/ }), /***/ "./node_modules/events/events.js": /*!***************************************!*\ !*** ./node_modules/events/events.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var R = typeof Reflect === 'object' ? Reflect : null var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) { return Function.prototype.apply.call(target, receiver, args); } var ReflectOwnKeys if (R && typeof R.ownKeys === 'function') { ReflectOwnKeys = R.ownKeys } else if (Object.getOwnPropertySymbols) { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target) .concat(Object.getOwnPropertySymbols(target)); }; } else { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target); }; } function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; } function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; module.exports.once = once; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._eventsCount = 0; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. var defaultMaxListeners = 10; function checkListener(listener) { if (typeof listener !== 'function') { throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); } } Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function() { return defaultMaxListeners; }, set: function(arg) { if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); } defaultMaxListeners = arg; } }); EventEmitter.init = function() { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { this._events = Object.create(null); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); } this._maxListeners = n; return this; }; function _getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); var doError = (type === 'error'); var events = this._events; if (events !== undefined) doError = (doError && events.error === undefined); else if (!doError) return false; // If there is no 'error' event listener then throw. if (doError) { var er; if (args.length > 0) er = args[0]; if (er instanceof Error) { // Note: The comments on the `throw` lines are intentional, they show // up in Node's output if this results in an unhandled exception. throw er; // Unhandled 'error' event } // At least give some kind of context to the user var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); err.context = er; throw err; // Unhandled 'error' event } var handler = events[type]; if (handler === undefined) return false; if (typeof handler === 'function') { ReflectApply(handler, this, args); } else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; checkListener(listener); events = target._events; if (events === undefined) { events = target._events = Object.create(null); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener !== undefined) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (existing === undefined) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; // If we've already got an array, just append. } else if (prepend) { existing.unshift(listener); } else { existing.push(listener); } // Check for listener leak m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; // No error code for this since it is a Warning // eslint-disable-next-line no-restricted-syntax var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; ProcessEmitWarning(w); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; if (arguments.length === 0) return this.listener.call(this.target); return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; checkListener(listener); events = this._events; if (events === undefined) return this; list = events[type]; if (list === undefined) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = Object.create(null); else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length - 1; i >= 0; i--) { if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (position === 0) list.shift(); else { spliceOne(list, position); } if (list.length === 1) events[type] = list[0]; if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener); } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events, i; events = this._events; if (events === undefined) return this; // not listening for removeListener, no need to emit if (events.removeListener === undefined) { if (arguments.length === 0) { this._events = Object.create(null); this._eventsCount = 0; } else if (events[type] !== undefined) { if (--this._eventsCount === 0) this._events = Object.create(null); else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = Object.keys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = Object.create(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners !== undefined) { // LIFO order for (i = listeners.length - 1; i >= 0; i--) { this.removeListener(type, listeners[i]); } } return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (events === undefined) return []; var evlistener = events[type]; if (evlistener === undefined) return []; if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events !== undefined) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener !== undefined) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; }; function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) copy[i] = arr[i]; return copy; } function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } function once(emitter, name) { return new Promise(function (resolve, reject) { function eventListener() { if (errorListener !== undefined) { emitter.removeListener('error', errorListener); } resolve([].slice.call(arguments)); }; var errorListener; // Adding an error listener is not optional because // if an error is thrown on an event emitter we cannot // guarantee that the actual event we are waiting will // be fired. The result could be a silent way to create // memory or file descriptor leaks, which is something // we should avoid. if (name !== 'error') { errorListener = function errorListener(err) { emitter.removeListener(name, eventListener); reject(err); }; emitter.once('error', errorListener); } emitter.once(name, eventListener); }); } /***/ }), /***/ "./node_modules/extend/index.js": /*!**************************************!*\ !*** ./node_modules/extend/index.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var hasOwn = Object.prototype.hasOwnProperty; var toStr = Object.prototype.toString; var defineProperty = Object.defineProperty; var gOPD = Object.getOwnPropertyDescriptor; var isArray = function isArray(arr) { if (typeof Array.isArray === 'function') { return Array.isArray(arr); } return toStr.call(arr) === '[object Array]'; }; var isPlainObject = function isPlainObject(obj) { if (!obj || toStr.call(obj) !== '[object Object]') { return false; } var hasOwnConstructor = hasOwn.call(obj, 'constructor'); var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); // Not own constructor property must be Object if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for (key in obj) { /**/ } return typeof key === 'undefined' || hasOwn.call(obj, key); }; // If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target var setProperty = function setProperty(target, options) { if (defineProperty && options.name === '__proto__') { defineProperty(target, options.name, { enumerable: true, configurable: true, value: options.newValue, writable: true }); } else { target[options.name] = options.newValue; } }; // Return undefined instead of __proto__ if '__proto__' is not an own property var getProperty = function getProperty(obj, name) { if (name === '__proto__') { if (!hasOwn.call(obj, name)) { return void 0; } else if (gOPD) { // In early versions of node, obj['__proto__'] is buggy when obj has // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. return gOPD(obj, name).value; } } return obj[name]; }; module.exports = function extend() { var options, name, src, copy, copyIsArray, clone; var target = arguments[0]; var i = 1; var length = arguments.length; var deep = false; // Handle a deep copy situation if (typeof target === 'boolean') { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { target = {}; } for (; i < length; ++i) { options = arguments[i]; // Only deal with non-null/undefined values if (options != null) { // Extend the base object for (name in options) { src = getProperty(target, name); copy = getProperty(options, name); // Prevent never-ending loop if (target !== copy) { // Recurse if we're merging plain objects or arrays if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && isArray(src) ? src : []; } else { clone = src && isPlainObject(src) ? src : {}; } // Never move original objects, clone them setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); // Don't bring in undefined values } else if (typeof copy !== 'undefined') { setProperty(target, { name: name, newValue: copy }); } } } } } // Return the modified object return target; }; /***/ }), /***/ "./node_modules/folder-pane/folderPane.js": /*!************************************************!*\ !*** ./node_modules/folder-pane/folderPane.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /* Folder pane ** ** This outline pane lists the members of a folder */ var UI = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js") var ns = UI.ns module.exports = { icon: UI.icons.iconBase + 'noun_973694_expanded.svg', name: 'folder', // Create a new folder in a Solid system, mintNew: function (context, newPaneOptions) { var kb = context.session.store var newInstance = newPaneOptions.newInstance || kb.sym(newPaneOptions.newBase) var u = newInstance.uri if (u.endsWith('/')) { u = u.slice(0, -1) // chop off trailer } // { throw new Error('URI of new folder must end in "/" :' + u) } newPaneOptions.newInstance = kb.sym(u + '/') // @@@@ kludge until we can get the solid-client version working // Force the folder by saving a dummy file inside it return kb.fetcher .webOperation('PUT', newInstance.uri + '.dummy', { contentType: 'application/octet-stream' }) .then(function () { console.log('New folder created: ' + newInstance.uri) return kb.fetcher.delete(newInstance.uri + '.dummy') }) .then(function () { console.log('Dummy file deleted : ' + newInstance.uri + '.dummy') /* return kb.fetcher.createContainer(parentURI, folderName) // Not BOTH ways }) .then(function () { */ console.log('New container created: ' + newInstance.uri) return newPaneOptions }) }, label: function (subject, context) { var kb = context.session.store var n = kb.each(subject, ns.ldp('contains')).length if (n > 0) { return 'Contents (' + n + ')' // Show how many in hover text } if (kb.holds(subject, ns.rdf('type'), ns.ldp('Container'))) { // It is declared as being a container return 'Container (0)' } return null // Suppress pane otherwise }, // Render a file folder in a LDP/solid system render: function (subject, context) { var dom = context.dom var outliner = context.getOutliner(dom) var kb = context.session.store var mainTable // This is a live synced table /* var complain = function complain (message, color) { var pre = dom.createElement('pre') console.log(message) pre.setAttribute('style', 'background-color: ' + color || '#eed' + ';') div.appendChild(pre) pre.appendChild(dom.createTextNode(message)) } */ var div = dom.createElement('div') div.setAttribute('class', 'instancePane') div.setAttribute( 'style', ' border-top: solid 1px #777; border-bottom: solid 1px #777; margin-top: 0.5em; margin-bottom: 0.5em ' ) // If this is an LDP container just list the directory var noHiddenFiles = function (obj) { // @@ This hiddenness should actually be server defined var pathEnd = obj.uri.slice(obj.dir().uri.length) return !( pathEnd.startsWith('.') || pathEnd.endsWith('.acl') || pathEnd.endsWith('~') ) } const thisDir = subject.uri.endsWith('/') ? subject.uri : subject.uri + '/' const indexThing = kb.sym(thisDir + 'index.ttl#this') if (kb.holds(subject, ns.ldp('contains'), indexThing.doc())) { console.log( 'View of folder with be view of indexThing. Loading ' + indexThing ) const packageDiv = div.appendChild(dom.createElement('div')) packageDiv.style.cssText = 'border-top: 0.2em solid #ccc;' // Separate folder views above from package views below kb.fetcher.load(indexThing.doc()).then(function () { mainTable = packageDiv.appendChild(dom.createElement('table')) context .getOutliner(dom) .GotoSubject(indexThing, true, undefined, false, undefined, mainTable) }) return div } else { mainTable = div.appendChild(dom.createElement('table')) var refresh = function () { var objs = kb.each(subject, ns.ldp('contains')).filter(noHiddenFiles) objs = objs.map(obj => [UI.utils.label(obj).toLowerCase(), obj]) objs.sort() // Sort by label case-insensitive objs = objs.map(pair => pair[1]) UI.utils.syncTableToArray(mainTable, objs, function (obj) { const st = kb.statementsMatching(subject, ns.ldp('contains'), obj)[0] const defaultpropview = outliner.VIEWAS_boring_default const tr = outliner.propertyTR(dom, st, false) tr.firstChild.textContent = '' // Was initialized to 'Contains' tr.firstChild.style.cssText += 'min-width: 3em;' tr.appendChild( outliner.outlineObjectTD(obj, defaultpropview, undefined, st) ) // UI.widgets.makeDraggable(tr, obj) return tr }) } mainTable.refresh = refresh refresh() } // Allow user to create new things within the folder var creationDiv = div.appendChild(dom.createElement('div')) var me = UI.authn.currentUser() var creationContext = { folder: subject, div: creationDiv, dom: dom, statusArea: creationDiv, me: me } creationContext.refreshTarget = mainTable UI.authn .filterAvailablePanes(context.session.paneRegistry.list) .then(function (relevantPanes) { UI.create.newThingUI(creationContext, context, relevantPanes) // Have to pass panes down newUI UI.aclControl.preventBrowserDropEvents(dom) const explictDropIcon = false var target if (explictDropIcon) { const iconStyleFound = creationDiv.firstChild.style.cssText target = creationDiv.insertBefore( dom.createElement('img'), creationDiv.firstChild ) target.style.cssText = iconStyleFound target.setAttribute('src', UI.icons.iconBase + 'noun_748003.svg') target.setAttribute('style', 'width: 2em; height: 2em') // Safari says target.style is read-only } else { target = creationDiv.firstChild // Overload drop target semantics onto the plus sign } // /////////// Allow new file to be Uploaded UI.widgets.makeDropTarget(target, null, droppedFileHandler) }) return div function droppedFileHandler (files) { UI.widgets.uploadFiles( kb.fetcher, files, subject.uri, subject.uri, function (file, uri) { // A file has been uploaded const destination = kb.sym(uri) console.log(' Upload: put OK: ' + destination) kb.add(subject, ns.ldp('contains'), destination, subject.doc()) mainTable.refresh() } ) } } } // ends /***/ }), /***/ "./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js": /*!**********************************************************************************!*\ !*** ./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js ***! \**********************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var reactIs = __webpack_require__(/*! react-is */ "./node_modules/react-is/index.js"); /** * Copyright 2015, Yahoo! Inc. * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ var REACT_STATICS = { childContextTypes: true, contextType: true, contextTypes: true, defaultProps: true, displayName: true, getDefaultProps: true, getDerivedStateFromError: true, getDerivedStateFromProps: true, mixins: true, propTypes: true, type: true }; var KNOWN_STATICS = { name: true, length: true, prototype: true, caller: true, callee: true, arguments: true, arity: true }; var FORWARD_REF_STATICS = { '$$typeof': true, render: true, defaultProps: true, displayName: true, propTypes: true }; var MEMO_STATICS = { '$$typeof': true, compare: true, defaultProps: true, displayName: true, propTypes: true, type: true }; var TYPE_STATICS = {}; TYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS; TYPE_STATICS[reactIs.Memo] = MEMO_STATICS; function getStatics(component) { // React v16.11 and below if (reactIs.isMemo(component)) { return MEMO_STATICS; } // React v16.12 and above return TYPE_STATICS[component['$$typeof']] || REACT_STATICS; } var defineProperty = Object.defineProperty; var getOwnPropertyNames = Object.getOwnPropertyNames; var getOwnPropertySymbols = Object.getOwnPropertySymbols; var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; var getPrototypeOf = Object.getPrototypeOf; var objectPrototype = Object.prototype; function hoistNonReactStatics(targetComponent, sourceComponent, blacklist) { if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components if (objectPrototype) { var inheritedComponent = getPrototypeOf(sourceComponent); if (inheritedComponent && inheritedComponent !== objectPrototype) { hoistNonReactStatics(targetComponent, inheritedComponent, blacklist); } } var keys = getOwnPropertyNames(sourceComponent); if (getOwnPropertySymbols) { keys = keys.concat(getOwnPropertySymbols(sourceComponent)); } var targetStatics = getStatics(targetComponent); var sourceStatics = getStatics(sourceComponent); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) { var descriptor = getOwnPropertyDescriptor(sourceComponent, key); try { // Avoid failures from read-only properties defineProperty(targetComponent, key, descriptor); } catch (e) {} } } } return targetComponent; } module.exports = hoistNonReactStatics; /***/ }), /***/ "./node_modules/hyphenate-style-name/index.js": /*!****************************************************!*\ !*** ./node_modules/hyphenate-style-name/index.js ***! \****************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* eslint-disable no-var, prefer-template */ var uppercasePattern = /[A-Z]/g var msPattern = /^ms-/ var cache = {} function toHyphenLower(match) { return '-' + match.toLowerCase() } function hyphenateStyleName(name) { if (cache.hasOwnProperty(name)) { return cache[name] } var hName = name.replace(uppercasePattern, toHyphenLower) return (cache[name] = msPattern.test(hName) ? '-' + hName : hName) } /* harmony default export */ __webpack_exports__["default"] = (hyphenateStyleName); /***/ }), /***/ "./node_modules/ieee754/index.js": /*!***************************************!*\ !*** ./node_modules/ieee754/index.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = (nBytes * 8) - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var nBits = -7 var i = isLE ? (nBytes - 1) : 0 var d = isLE ? -1 : 1 var s = buffer[offset + i] i += d e = s & ((1 << (-nBits)) - 1) s >>= (-nBits) nBits += eLen for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} m = e & ((1 << (-nBits)) - 1) e >>= (-nBits) nBits += mLen for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { e = 1 - eBias } else if (e === eMax) { return m ? NaN : ((s ? -1 : 1) * Infinity) } else { m = m + Math.pow(2, mLen) e = e - eBias } return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { var e, m, c var eLen = (nBytes * 8) - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) var i = isLE ? 0 : (nBytes - 1) var d = isLE ? 1 : -1 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 value = Math.abs(value) if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0 e = eMax } else { e = Math.floor(Math.log(value) / Math.LN2) if (value * (c = Math.pow(2, -e)) < 1) { e-- c *= 2 } if (e + eBias >= 1) { value += rt / c } else { value += rt * Math.pow(2, 1 - eBias) } if (value * c >= 2) { e++ c /= 2 } if (e + eBias >= eMax) { m = 0 e = eMax } else if (e + eBias >= 1) { m = ((value * c) - 1) * Math.pow(2, mLen) e = e + eBias } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) e = 0 } } for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} e = (e << mLen) | m eLen += mLen for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} buffer[offset + i - d] |= s * 128 } /***/ }), /***/ "./node_modules/inherits/inherits_browser.js": /*!***************************************************!*\ !*** ./node_modules/inherits/inherits_browser.js ***! \***************************************************/ /*! no static exports found */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }) } }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } } /***/ }), /***/ "./node_modules/is-buffer/index.js": /*!*****************************************!*\ !*** ./node_modules/is-buffer/index.js ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { /*! * Determine if an object is a Buffer * * @author Feross Aboukhadijeh * @license MIT */ module.exports = function isBuffer (obj) { return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) } /***/ }), /***/ "./node_modules/is-in-browser/dist/module.js": /*!***************************************************!*\ !*** ./node_modules/is-in-browser/dist/module.js ***! \***************************************************/ /*! exports provided: isBrowser, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isBrowser", function() { return isBrowser; }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var isBrowser = (typeof window === "undefined" ? "undefined" : _typeof(window)) === "object" && (typeof document === "undefined" ? "undefined" : _typeof(document)) === 'object' && document.nodeType === 9; /* harmony default export */ __webpack_exports__["default"] = (isBrowser); /***/ }), /***/ "./node_modules/is-plain-obj/index.js": /*!********************************************!*\ !*** ./node_modules/is-plain-obj/index.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = value => { if (Object.prototype.toString.call(value) !== '[object Object]') { return false; } const prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; }; /***/ }), /***/ "./node_modules/isarray/index.js": /*!***************************************!*\ !*** ./node_modules/isarray/index.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; /***/ }), /***/ "./node_modules/issue-pane/board.js": /*!******************************************!*\ !*** ./node_modules/issue-pane/board.js ***! \******************************************/ /*! exports provided: board */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "board", function() { return board; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /** A Board of vertical columns * * Like a github "project", or a kanbam board, a board allows * you to triage stuff into simple cateories. * * if an object is added in a refresh, then a new column should be added if needed * if its value is previously unseen * (Should the coluimn order be defined by user or caller?) * * @returns dom:Element */ const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] function board (dom, columnValues, renderItem, options) { const board = dom.createElement('div') board.style = 'width: 100%;' board.style.margin = '1em' const table = board.appendChild(dom.createElement('table')) table.style = 'width: 100%;' table.style.borderCollapse = 'collapse' const headerRow = table.appendChild(dom.createElement('tr')) const mainRow = table.appendChild(dom.createElement('tr')) columnValues.forEach(x => { const cell = headerRow.appendChild(dom.createElement('th')) cell.textContent = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(x, true) // Initial capital cell.subject = x cell.style = 'margin: 0.3em; padding: 0.5em 1em; font-treatment: bold; font-size: 120%;' const column = mainRow.appendChild(dom.createElement('td')) column.subject = x column.style = 'border: 0.01em solid white; padding: 0.1em;' // display: flex; flex-direction: column; align-items: center; function droppedURIHandler (uris) { uris.forEach(function (u) { console.log('Dropped on column: ' + u) const item = kb.sym(u) options.columnDropHandler(item, x) }) } if (options.columnDropHandler) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDropTarget(column, droppedURIHandler) } }) /* Each item on the board * normally App will override this */ function defaultRenderItem (item, category) { const card = dom.createElement('div') const table = card.appendChild(dom.createElement('table')) const classes = kb.each(item, ns.rdf('type')) const catColors = classes.map(cat => kb.any(cat, ns.ui('backgroundColor'))).filter(c => c) table.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].personTR(dom, null, item)) table.subject = item table.style = 'margin: 1em;' // @@ use style.js const backgroundColor = catColors[0] || kb.any(category, ns.ui('backgroundColor')) card.style.backgroundColor = backgroundColor ? backgroundColor.value : '#fff' return card } function sortedBy (values, predicate, defaultSortValue, reverse) { const toBeSorted = values.map(x => [kb.any(x, predicate) || defaultSortValue, x]) toBeSorted.sort() if (reverse) toBeSorted.reverse() // @@ check return toBeSorted.map(pair => pair[1]) } board.refresh = function () { const now = new $rdf.Literal(new Date()) const actualRenderItem = renderItem || options.renderItem || defaultRenderItem function localRenderItem (subject) { const ele = actualRenderItem(subject) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeDraggable(ele, subject) ele.subject = subject return ele } for (let col = mainRow.firstChild; col; col = col.nextSibling) { const category = col.subject let items = kb.each(null, ns.rdf('type'), category) const sortBy = options.sortBy || ns.dct('created') if (options.filter) { items = items.filter(options.filter) } const sortedItems = sortedBy(items, sortBy, now, true) solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].syncTableToArrayReOrdered(col, sortedItems, localRenderItem) } } // kb.query(query, addCellFromBindings, undefined, whenDone) // Populate the board board.refresh() return board } /***/ }), /***/ "./node_modules/issue-pane/issue.js": /*!******************************************!*\ !*** ./node_modules/issue-pane/issue.js ***! \******************************************/ /*! exports provided: getState, renderIssueCard, exposeOverlay, renderIssue */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getState", function() { return getState; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderIssueCard", function() { return renderIssueCard; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exposeOverlay", function() { return exposeOverlay; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderIssue", function() { return renderIssue; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _newIssue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./newIssue */ "./node_modules/issue-pane/newIssue.js"); // All the UI for a single issue, without store load or listening for changes // const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const SET_MODIFIED_DATES = false function complain (message, context) { console.warn(message) context.paneDiv.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(context.dom, message)) } function getState (issue, classification) { const tracker = kb.the(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('tracker'), null, issue.doc()) const states = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('issueClass')) classification = classification || states const types = kb.each(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].rdf('type')) .filter(ty => kb.holds(ty, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].rdfs('subClassOf'), classification)) if (types.length !== 1) { // const initialState = kb.any(tracker, ns.wf('initialState')) No do NOT default // if (initialState) return initialState throw new Error('Issue must have one type as state: ' + types.length) } return types[0] } function renderIssueCard (issue, context) { function getBackgroundColor () { const classes = kb.each(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].rdf('type')) // @@ pick cats in order then state const catColors = classes.map(cat => kb.any(cat, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].ui('backgroundColor'))).filter(c => !!c) if (catColors.length) return catColors[0].value // pick first one return null } function refresh () { const backgroundColor = getBackgroundColor() || 'white' card.style.backgroundColor = backgroundColor editButton.style.backgroundColor = backgroundColor // Override white from style sheet } const dom = context.dom const uncategorized = !getBackgroundColor() // This is a suspect issue. Prompt to delete it const card = dom.createElement('div') const table = card.appendChild(dom.createElement('table')) table.style.width = '100%' const options = { draggable: false } // Let the baord make th ewhole card draggable table.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].personTR(dom, null, issue, options)) table.subject = issue card.style = 'border-radius: 0.4em; border: 0.05em solid grey; margin: 0.3em;' const img = card.firstChild.firstChild.firstChild.firstChild // div/table/tr/td/img img.setAttribute('src', solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_Danger_1259514.svg') // override // Add a button for viewing the whole issue in overlay const buttonsCell = card.firstChild.firstChild.children[2] // right hand part of card const editButton = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].button(dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_253504.svg', 'edit', async _event => { exposeOverlay(issue, context) }) const editButtonImage = editButton.firstChild editButtonImage.style.width = editButtonImage.style.height = '1.5em' buttonsCell.appendChild(editButton) // If uncategorized, shortcut to delete issue if (uncategorized) { const deleteButton = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].deleteButtonWithCheck(dom, buttonsCell, 'issue', async function () { // noun? try { await kb.updater.update(kb.connectedStatements(issue)) } catch (err) { complain(`Unable to delete issue: ${err}`, context) } console.log('User deleted issue ' + issue) card.parentNode.removeChild(card) // refresh doesn't work yet because it is not passed though tabs so short cut solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(context.paneDiv) // Should delete the card if nec when tabs pass it though // complain('DELETED OK', context) }) buttonsCell.appendChild(deleteButton) } card.style.maxWidth = '24em' // @@ User adjustable?? card.refresh = refresh refresh() return card } function exposeOverlay (subject, context) { function hideOverlay () { overlay.innerHTML = '' // clear overlay overlay.style.visibility = 'hidden' } const overlay = context.overlay overlay.innerHTML = '' // clear existing const button = overlay.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].button(context.dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_1180156.svg', 'close', hideOverlay)) button.style.float = 'right' button.style.margin = '0.7em' delete button.style.backgroundColor // do not want white overlay.style.visibility = 'visible' overlay.appendChild(renderIssue(subject, context)) overlay.firstChild.style.overflow = 'auto' // was scroll } function renderIssue (issue, context) { // Don't bother changing the last modified dates of things: save time function setModifiedDate (subj, kb, doc) { if (SET_MODIFIED_DATES) { if (!getOption(tracker, 'trackLastModified')) return let deletions = kb.statementsMatching(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].dct('modified')) deletions = deletions.concat( kb.statementsMatching(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('modifiedBy')) ) const insertions = [$rdf.st(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].dct('modified'), new Date(), doc)] if (me) insertions.push($rdf.st(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('modifiedBy'), me, doc)) kb.updater.update(deletions, insertions, function (_uri, _ok, _body) {}) } } function say (message, style) { const pre = dom.createElement('pre') pre.setAttribute('style', style || 'color: grey') issueDiv.appendChild(pre) pre.appendChild(dom.createTextNode(message)) return pre } const timestring = function () { const now = new Date() return '' + now.getTime() // http://www.w3schools.com/jsref/jsref_obj_date.asp } function complain (message) { console.warn(message) issueDiv.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message)) } function complainIfBad (ok, body) { if (!ok) { complain( 'Sorry, failed to save your change:\n' + body, 'background-color: pink;', context ) } } function getOption (tracker, option) { // eg 'allowSubIssues' const opt = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].ui(option)) return !!(opt && opt.value) } function setPaneStyle () { const types = kb.findTypeURIs(issue) let mystyle = 'padding: 0.5em 1.5em 1em 1.5em; ' let backgroundColor = null for (const uri in types) { backgroundColor = kb.any( kb.sym(uri), kb.sym('http://www.w3.org/ns/ui#backgroundColor') ) if (backgroundColor) break } backgroundColor = backgroundColor ? backgroundColor.value : '#eee' // default grey mystyle += 'background-color: ' + backgroundColor + '; ' issueDiv.setAttribute('style', mystyle) } const dom = context.dom const tracker = kb.the(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('tracker'), null, issue.doc()) if (!tracker) throw new Error('No tracker') const stateStore = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('stateStore')) const store = issue.doc() const issueDiv = dom.createElement('div') var me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() setPaneStyle() solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].checkUser() // kick off async operation const states = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('issueClass')) if (!states) { throw new Error('This tracker ' + tracker + ' has no issueClass') } const select = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeSelectForCategory( dom, kb, issue, states, stateStore, function (ok, body) { if (ok) { setModifiedDate(store, kb, store) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(issueDiv) } else { console.log('Failed to change state:\n' + body) } } ) issueDiv.appendChild(select) const cats = kb.each(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('issueCategory')) // zero or more for (let i = 0; i < cats.length; i++) { issueDiv.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeSelectForCategory( dom, kb, issue, cats[i], stateStore, function (ok, body) { if (ok) { setModifiedDate(store, kb, store) solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(issueDiv) } else { console.log('Failed to change category:\n' + body) } } ) ) } // For when issue is the main solo subject, include link to tracker itself. const a = dom.createElement('a') a.setAttribute('href', tracker.uri) a.setAttribute('style', 'float:right') issueDiv.appendChild(a).textContent = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(tracker) a.addEventListener('click', solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].openHrefInOutlineMode, true) // Main Form for Title, description only const coreIssueFormText = ` @prefix : . @prefix core: . @prefix dc: . @prefix wf: . core:coreIsueForm a :Form; "Core issue data"; :parts ( core:titleField core:descriptionField ) . core:descriptionField a :MultiLineTextField; :label "Description"; :property wf:description; :size "40" . core:titleField a :SingleLineTextField; :label "Title"; :maxLength "128"; :property dc:title; # @@ Should move to dct or schema :size "40" . wf:Task :creationForm core:coreIsueForm . ` const CORE_ISSUE_FORM = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('coreIsueForm') $rdf.parse(coreIssueFormText, kb, CORE_ISSUE_FORM.doc().uri, 'text/turtle') solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].appendForm( dom, issueDiv, {}, issue, CORE_ISSUE_FORM, stateStore, complainIfBad ) // Descriptions can be long and are stored local to the issue /* issueDiv.appendChild( widgets.makeDescription( dom, kb, issue, ns.wf('description'), store, function (ok, body) { if (ok) setModifiedDate(store, kb, store) else console.log('Failed to change description:\n' + body) } ) ) */ // Assigned to whom? const assignments = kb.statementsMatching(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('assignee')) if (assignments.length > 1) { say('Weird, was assigned to more than one person. Fixing ..') const deletions = assignments.slice(1) kb.updater.update(deletions, [], function (uri, ok, body) { if (ok) { say('Now fixed.') } else { complain('Fixed failed: ' + body, context) } }) } // Who could be assigned to this? // Anyone assigned to any issue we know about async function getPossibleAssignees () { let devs = [] const devGroups = kb.each(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('assigneeGroup')) for (let i = 0; i < devGroups.length; i++) { const group = devGroups[i] await kb.fetcher.load() devs = devs.concat(kb.each(group, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].vcard('member'))) } // Anyone who is a developer of any project which uses this tracker const proj = kb.any(null, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].doap('bug-database'), tracker) // What project? if (proj) { await kb.fetcher.load(proj) devs = devs.concat(kb.each(proj, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].doap('developer'))) } return devs } // Super issues first - like parent directories .. maybe use breadcrums from?? @@ function renderSubIssue (issue) { const options = { link: false } return solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].personTR(dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('dependent'), issue, options) } getPossibleAssignees().then(devs => { if (devs.length) { devs.forEach(function (person) { kb.fetcher.lookUpThing(person) }) // best effort async for names etc const opts = { // 'mint': '** Add new person **', nullLabel: '(unassigned)' /* 'mintStatementsFun': function (newDev) { var sts = [ $rdf.st(newDev, ns.rdf('type'), ns.foaf('Person')) ] if (proj) sts.push($rdf.st(proj, ns.doap('developer'), newDev)) return sts } */ } issueDiv.appendChild( solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].makeSelectForOptions( dom, kb, issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('assignee'), devs, opts, store, function (ok, body) { if (ok) setModifiedDate(store, kb, store) else console.log('Failed to change assignee:\n' + body) } ) ) } }) /* The trees of super issues and subissues */ let subIssuePanel if (getOption(tracker, 'allowSubIssues')) { if (!subIssuePanel) { subIssuePanel = issueDiv.appendChild(dom.createElement('div')) subIssuePanel.style = 'margin: 1em; padding: 1em;' } subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Super Issues' const listOfSupers = subIssuePanel.appendChild(dom.createElement('div')) listOfSupers.refresh = function () { solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].syncTableToArrayReOrdered(listOfSupers, kb.each(null, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('dependent'), issue), renderSubIssue) } listOfSupers.refresh() // Sub issues subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Sub Issues' const listOfSubs = subIssuePanel.appendChild(dom.createElement('div')) listOfSubs.refresh = function () { solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].syncTableToArrayReOrdered(listOfSubs, kb.each(issue, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('dependent')), renderSubIssue) } listOfSubs.refresh() const b = dom.createElement('button') b.setAttribute('type', 'button') subIssuePanel.appendChild(b) const classLabel = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(states) b.innerHTML = 'New sub ' + classLabel b.setAttribute('style', 'float: right; margin: 0.5em 1em;') b.addEventListener( 'click', function (_event) { subIssuePanel.insertBefore(Object(_newIssue__WEBPACK_IMPORTED_MODULE_1__["newIssueForm"])(dom, kb, tracker, issue, listOfSubs.refresh), b.nextSibling) // Pop form just after button }, false ) } issueDiv.appendChild(dom.createElement('br')) // Extras are stored centrally to the tracker const extrasForm = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('extrasEntryForm')) if (extrasForm) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].appendForm( dom, issueDiv, {}, issue, extrasForm, stateStore, complainIfBad ) } // Comment/discussion area const spacer = issueDiv.appendChild(dom.createElement('tr')) spacer.setAttribute('style', 'height: 1em') // spacer and placeHolder const template = kb.anyValue(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('issueURITemplate')) /* var chatDocURITemplate = kb.anyValue(tracker, ns.wf('chatDocURITemplate')) // relaive to issue var chat if (chatDocURITemplate) { let template = $rdf.uri.join(chatDocURITemplate, issue.uri) // Template is relative to issue chat = kb.sym(expandTemplate(template)) } else */ let messageStore if (template) { messageStore = issue.doc() // for now. Could go deeper } else { messageStore = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('messageStore')) if (!messageStore) messageStore = kb.any(tracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('stateStore')) kb.sym(messageStore.uri + '#' + 'Chat' + timestring()) // var chat = } kb.fetcher.nowOrWhenFetched(messageStore, function (ok, body, _xhr) { if (!ok) { const er = dom.createElement('p') er.textContent = body // @@ use nice error message issueDiv.insertBefore(er, spacer) } else { const discussion = Object(solid_ui__WEBPACK_IMPORTED_MODULE_0__["messageArea"])(dom, kb, issue, messageStore) issueDiv.insertBefore(discussion, spacer) } }) // Draggable attachment list const attachmentHint = issueDiv.appendChild(dom.createElement('div')) attachmentHint.innerHTML = `

Attachments

Drag files, emails, web pages onto the paper clip, or click the file upload button.

` let uploadFolderURI if (issue.uri.endsWith('/index.ttl#this')) { // This has a whole folder to itself uploadFolderURI = issue.uri.slice(0, 14) + 'Files/' // back to slash } else { // like state.ttl#Iss1587852322438 uploadFolderURI = issue.dir().uri + 'Files/' + issue.uri.split('#')[1] + '/' // New folder for issue in file with others } solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].attachmentList(dom, issue, issueDiv, { doc: stateStore, promptIcon: solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_25830.svg', uploadFolder: kb.sym(uploadFolderURI), // Allow local files to be uploaded predicate: solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('attachment') }) // Delete button to delete the issue const deleteButton = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].deleteButtonWithCheck(dom, issueDiv, 'issue', async function () { try { await kb.updater.update(kb.connectedStatements(issue)) } catch (err) { complain(`Unable to delete issue: ${err}`, context) } // @@ refreshTree complain('DELETED OK', context) issueDiv.style.backgroundColor = '#eee' issueDiv.style.fontColor = 'orange' }) deleteButton.style.float = 'right' // Refresh button const refreshButton = dom.createElement('button') refreshButton.textContent = 'refresh messages' refreshButton.addEventListener( 'click', async function (_event) { try { await kb.fetcher.load(messageStore, { force: true, clearPreviousData: true }) } catch (err) { alert(err) return } solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(issueDiv) }, false ) refreshButton.setAttribute('style', solid_ui__WEBPACK_IMPORTED_MODULE_0__["style"].button) issueDiv.appendChild(refreshButton) return issueDiv } // renderIssue /***/ }), /***/ "./node_modules/issue-pane/issuePane.js": /*!**********************************************!*\ !*** ./node_modules/issue-pane/issuePane.js ***! \**********************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _board__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./board */ "./node_modules/issue-pane/board.js"); /* harmony import */ var _issue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./issue */ "./node_modules/issue-pane/issue.js"); /* harmony import */ var _newTracker__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./newTracker */ "./node_modules/issue-pane/newTracker.js"); /* harmony import */ var _newIssue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./newIssue */ "./node_modules/issue-pane/newIssue.js"); /* harmony import */ var _trackerSettingsForm_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./trackerSettingsForm.js */ "./node_modules/issue-pane/trackerSettingsForm.js"); /* Issue Tracker Pane ** ** This solid view allows a user to interact with an issue tracker, or individual issue, ** to change its state according to an ontology, comment on it, etc. ** */ // @@ will later be in solid-UI // import { trackerInstancesFormText } from './trackerInstancesForm.js' const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const widgets = solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"] // const MY_TRACKERS_ICON = UI.icons.iconBase + 'noun_Document_998605.svg' // const TRACKER_ICON = UI.icons.iconBase + 'noun_list_638112' // const TASK_ICON = UI.icons.iconBase + 'noun_17020.svg' const OVERFLOW_STYLE = 'position: fixed; top: 1.51em; right: 2em; left: 2em; bottom:1.5em; border: 0.1em grey; overflow: scroll;' /* harmony default export */ __webpack_exports__["default"] = ({ icon: solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_122196.svg', // was: js/panes/issue/tbl-bug-22.png // noun_list_638112 is a checklist document // noun_Document_998605.svg is a stack of twpo checklists // noun_97839.svg is a ladybug // noun_122196.svg is a clipboard with a check list on it // noun_17020.svg is a single check box name: 'issue', audience: [], // Anyone. was [ns.solid('PowerUser')] // Does the subject deserve an issue pane? label: function (subject, _context) { const t = kb.findTypeURIs(subject) if ( t['http://www.w3.org/2005/01/wf/flow#Task'] || kb.holds(subject, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('tracker')) ) { return 'issue' } // in case ontology not available if (t['http://www.w3.org/2005/01/wf/flow#Tracker']) return 'tracker' // Later: Person. For a list of things assigned to them, // open bugs on projects they are developer on, etc return null // No under other circumstances (while testing at least!) }, mintClass: ns.wf('Tracker'), mintNew: async function (context, options) { /** Perform updates on more than one document @@ Move to rdflib! */ async function updateMany (deletions, insertions) { const docs = deletions.concat(insertions).map(st => st.why) const uniqueDocs = Array.from(new Set(docs)) const updates = uniqueDocs.map(doc => kb.updater.update(deletions.filter(st => st.why.sameTerm(doc)), insertions.filter(st => st.why.sameTerm(doc)))) return Promise.all(updates) } var kb = context.session.store const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] let stateStore if (options.newInstance) { stateStore = kb.sym(options.newInstance.doc().uri + '_state.ttl') } else { options.newInstance = kb.sym(options.newBase + 'index.ttl#this') stateStore = kb.sym(options.newBase + 'state.ttl') } const tracker = options.newInstance const appDoc = tracker.doc() const me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() if (me) { kb.add(tracker, ns.dc('author'), me, appDoc) } kb.add(tracker, ns.rdf('type'), ns.wf('Tracker'), appDoc) kb.add(tracker, ns.dc('created'), new Date(), appDoc) // @@ to do --- adk user what sort of tracker they want kb.add(tracker, ns.wf('issueClass'), ns.wf('Task'), appDoc) // @@ ask user kb.add(tracker, ns.wf('initialState'), ns.wf('Open'), appDoc) kb.add(tracker, ns.wf('stateStore'), stateStore, appDoc) kb.add(tracker, ns.wf('assigneeClass'), ns.foaf('Person'), appDoc) // @@ set to people in the meeting? kb.add(tracker, ns.wf('stateStore'), stateStore, stateStore) // Back Link const ins = kb.statementsMatching(undefined, undefined, undefined, appDoc).concat(kb.statementsMatching(undefined, undefined, undefined, stateStore)) try { await updateMany([], ins) } catch (err) { return solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].complain(context, 'Error writing tracker configuration: ' + err) } /* try { await kb.updater.updateMany([], kb.statementsMatching(undefined, undefined, undefined, stateStore)) } catch (err) { return UI.widgets.complain(context, 'Error writing tracker state file: ' + err) } */ const dom = context.dom const div = options.div const notice = div.appendChild(dom.createElement('div')) notice.innerHTML = `

Success

Your new tracker has been made. Use the settings tab to configure it.

` // console.log('New tracker created ' + tracker) // alert('New tracker created') return options }, render: function (subject, context) { const dom = context.dom const paneDiv = dom.createElement('div') context.paneDiv = paneDiv paneDiv.setAttribute('class', 'issuePane') function complain (message) { console.warn(message) paneDiv.appendChild(solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].errorMessageBlock(dom, message)) } function complainIfBad (ok, message) { if (!ok) { complain(message) } } /** Infer subclass from disjoint Union ** ** This is would not be needed if our quey language ** allowed is to query ardf Collection membership. */ async function fixSubClasses (kb, tracker) { async function checkOneSuperclass (klass) { const collection = kb.any(klass, ns.owl('disjointUnionOf'), null, doc) if (!collection) throw new Error(`Classification ${klass} has no disjointUnionOf`) if (!collection.elements) throw new Error(`Classification ${klass} has no array`) const needed = new Set(collection.elements.map(x => x.uri)) const existing = new Set(kb.each(null, ns.rdfs('subClassOf'), klass, doc) .map(x => x.uri)) for (const sub of existing) { if (!needed.has(sub)) { deletables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc)) } } for (const sub of needed) { if (!existing.has(sub)) { insertables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc)) } } } const doc = tracker.doc() const states = kb.any(tracker, ns.wf('issueClass')) const cats = kb.each(tracker, ns.wf('issueCategory')) var insertables = [] var deletables = [] cats.push(states) for (const klass of cats) { await checkOneSuperclass(klass) } const damage = insertables.length + deletables.length if (damage) { alert(`Internal error: s${damage} subclasses inconsistences!`) /* if (confirm(`Fix ${damage} inconsistent subclasses in tracker config?`)) { await kb.updater.update(deletables, insertables) */ } } /** /////////////////////////// Board */ function renderBoard (tracker, klass) { const states = kb.any(tracker, ns.wf('issueClass')) klass = klass || states // default to states const doingStates = klass.sameTerm(states) // These are states we will show by default: the open issues. const stateArray = kb.any(klass, ns.owl('disjointUnionOf')) if (!stateArray) { return complain(`Configuration error: state ${states} does not have substates`) } let columnValues = stateArray.elements if (doingStates && columnValues.length > 2 // and there are more than two ) { // strip out closed states columnValues = columnValues.filter(state => kb.holds(state, ns.rdfs('subClassOf'), ns.wf('Open')) || state.sameTerm(ns.wf('Open'))) } async function columnDropHandler (issue, newState) { const currentState = Object(_issue__WEBPACK_IMPORTED_MODULE_2__["getState"])(issue, klass) const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc()) const stateStore = kb.any(tracker, ns.wf('stateStore')) if (newState.sameTerm(currentState)) { // alert('Same state ' + UI.utils.label(currentState)) // @@ remove return } try { await kb.updater.update( [$rdf.st(issue, ns.rdf('type'), currentState, stateStore)], [$rdf.st(issue, ns.rdf('type'), newState, stateStore)]) } catch (err) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].complain(context, 'Unable to change issue state: ' + err) } boardDiv.refresh() // reorganize board to match the new reality } function isOpen (issue) { const types = kb.findTypeURIs(issue) return !!types[ns.wf('Open').uri] } const options = { columnDropHandler, filter: doingStates ? null : isOpen } options.sortBy = ns.dct('created') options.sortReverse = true function localRenderIssueCard (issue) { return Object(_issue__WEBPACK_IMPORTED_MODULE_2__["renderIssueCard"])(issue, context) } // const columnValues = states // @@ optionally selected states would work const boardDiv = Object(_board__WEBPACK_IMPORTED_MODULE_1__["board"])(dom, columnValues, localRenderIssueCard, options) return boardDiv } /** ////////////// Table */ function tableRefreshButton (stateStore, tableDiv) { const refreshButton = widgets.button(dom, solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_479395.svg', 'refresh table', async _event => { try { await kb.fetcher.load(stateStore, { force: true, clearPreviousData: true }) } catch (err) { alert(err) return } solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(tableDiv) }) return refreshButton } function renderTable (tracker) { function newOptionalClause () { const clause = new $rdf.IndexedFormula() query.pat.optional.push(clause) return clause } const states = kb.any(subject, ns.wf('issueClass')) const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more const vars = ['issue', 'state', 'created'] var query = new $rdf.Query(solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(subject)) for (let i = 0; i < cats.length; i++) { vars.push('_cat_' + i) } const v = {} // The RDF variable objects for each variable name vars.forEach(function (x) { query.vars.push((v[x] = $rdf.variable(x))) }) query.pat.add(v.issue, ns.wf('tracker'), tracker) // query.pat.add(v['issue'], ns.dc('title'), v['title']) query.pat.add(v.issue, ns.dct('created'), v.created) query.pat.add(v.issue, ns.rdf('type'), v.state) query.pat.add(v.state, ns.rdfs('subClassOf'), states) query.pat.optional = [] for (let i = 0; i < cats.length; i++) { const clause = newOptionalClause() clause.add(v.issue, ns.rdf('type'), v['_cat_' + i]) clause.add(v['_cat_' + i], ns.rdfs('subClassOf'), cats[i]) } const propertyList = kb.any(tracker, ns.wf('propertyList')) // List of extra properties if (propertyList) { const properties = propertyList.elements for (let p = 0; p < properties.length; p++) { const prop = properties[p] let vname = '_prop_' + p if (prop.uri.indexOf('#') >= 0) { vname = prop.uri.split('#')[1] } const oneOpt = newOptionalClause() query.vars.push((v[vname] = $rdf.variable(vname))) oneOpt.add(v.issue, prop, v[vname]) } } const selectedStates = {} const possible = kb.each(undefined, ns.rdfs('subClassOf'), states) possible.forEach(function (s) { if ( kb.holds(s, ns.rdfs('subClassOf'), ns.wf('Open')) || s.sameTerm(ns.wf('Open')) ) { selectedStates[s.uri] = true // console.log('on '+s.uri); // @@ } }) function exposeThisOverlay (href) { const subject = $rdf.sym(href) Object(_issue__WEBPACK_IMPORTED_MODULE_2__["exposeOverlay"])(subject, context) } const tableDiv = solid_ui__WEBPACK_IMPORTED_MODULE_0__["table"](dom, { query: query, keyVariable: '?issue', // Charactersic of row sortBy: '?created', // By default, sort by date sortReverse: true, // most recent at the top hints: { '?issue': { linkFunction: exposeThisOverlay, label: 'Title' }, '?created': { cellFormat: 'shortDate' }, '?state': { initialSelection: selectedStates, label: 'Status' } } }) const stateStore = kb.any(subject, ns.wf('stateStore')) tableDiv.appendChild(tableRefreshButton(stateStore, tableDiv)) return tableDiv } // Allow user to create new things within the folder function renderCreationControl (refreshTarget) { const creationDiv = dom.createElement('div') const me = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].currentUser() const creationContext = { // folder: subject, div: creationDiv, dom: dom, noun: 'tracker', statusArea: creationDiv, me: me, refreshTarget: refreshTarget } const issuePane = context.session.paneRegistry.byName('issue') const relevantPanes = [issuePane] solid_ui__WEBPACK_IMPORTED_MODULE_0__["create"].newThingUI(creationContext, context, relevantPanes) // Have to pass panes down newUI return creationDiv } function renderInstances (theClass) { const instancesDiv = dom.createElement('div') const context = { dom, div: instancesDiv, noun: 'tracker' } solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].registrationList(context, { public: true, private: true, type: theClass }).then(_context2 => { instancesDiv.appendChild(renderCreationControl(instancesDiv)) /* // keep this code in case we need a form const InstancesForm = ns.wf('TrackerInstancesForm') const text = trackerInstancesFormText $rdf.parse(text, kb, InstancesForm.doc().uri, 'text/turtle') widgets.appendForm(dom, instancesDiv, {}, tracker, InstancesForm, tracker.doc(), complainIfBad) */ }) return instancesDiv } function renderSettings (tracker) { const settingsDiv = dom.createElement('div') // A registration control allows the to record this tracker in their type index const context = { dom, div: settingsDiv, noun: 'tracker' } solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].registrationControl(context, tracker, ns.wf('Tracker')).then(_context2 => { const settingsForm = ns.wf('TrackerSettingsForm') const text = _trackerSettingsForm_js__WEBPACK_IMPORTED_MODULE_5__["trackerSettingsFormText"] $rdf.parse(text, kb, settingsForm.doc().uri, 'text/turtle') widgets.appendForm(dom, settingsDiv, {}, tracker, settingsForm, tracker.doc(), complainIfBad) }) return settingsDiv } function renderTabsTableAndBoard () { function renderMain (ele, object) { ele.innerHTML = '' // Clear out "loading message" if (object.sameTerm(boardView)) { ele.appendChild(renderBoard(tracker)) } else if (object.sameTerm(tableView)) { ele.appendChild(renderTable(tracker)) } else if (object.sameTerm(settingsView)) { ele.appendChild(renderSettings(tracker)) } else if (object.sameTerm(instancesView)) { ele.appendChild(renderInstances(ns.wf('Tracker'))) } else if ((kb.holds(tracker, ns.wf('issueCategory'), object)) || (kb.holds(tracker, ns.wf('issueClass'), object))) { ele.appendChild(renderBoard(tracker, object)) } else { throw new Error('Unexpected tab type: ' + object) } } const states = kb.any(tracker, ns.wf('issueClass')) const items = [instancesView, tableView, states] .concat(kb.each(tracker, ns.wf('issueCategory'))) items.push(settingsView) const selectedTab = tableView const options = { renderMain, items, selectedTab } // Add stuff to the ontologies which we believe but they don't say const doc = instancesView.doc() kb.add(instancesView, ns.rdfs('label'), 'My Trackers', doc) // @@ squatting on wf ns kb.add(settingsView, ns.rdfs('label'), 'Settings', doc) // @@ squatting on wf ns kb.add(states, ns.rdfs('label'), 'By State', doc) // @@ squatting on wf ns const tabs = solid_ui__WEBPACK_IMPORTED_MODULE_0__["tabs"].tabWidget(options) return tabs } async function renderTracker () { function showNewIssue (issue) { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(paneDiv) Object(_issue__WEBPACK_IMPORTED_MODULE_2__["exposeOverlay"])(issue, context) b.disabled = false // https://stackoverflow.com/questions/41176582/enable-disable-a-button-in-pure-javascript } tracker = subject try { await fixSubClasses(kb, tracker) } catch (err) { console.log('@@@ Error fixing subclasses in config: ' + err) } const states = kb.any(subject, ns.wf('issueClass')) if (!states) throw new Error('This tracker has no issueClass') const stateStore = kb.any(subject, ns.wf('stateStore')) if (!stateStore) throw new Error('This tracker has no stateStore') solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].checkUser() // kick off async operation const h = dom.createElement('h2') h.setAttribute('style', 'font-size: 150%') paneDiv.appendChild(h) const classLabel = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(states) h.appendChild(dom.createTextNode(classLabel + ' list')) // Use class label @@I18n // New Issue button var b = dom.createElement('button') const container = dom.createElement('div') b.setAttribute('type', 'button') b.setAttribute('style', 'padding: 0.3em; font-size: 100%; margin: 0.5em;') container.appendChild(b) paneDiv.appendChild(container) const img = dom.createElement('img') img.setAttribute('src', solid_ui__WEBPACK_IMPORTED_MODULE_0__["icons"].iconBase + 'noun_19460_green.svg') img.setAttribute('style', 'width: 1em; height: 1em; margin: 0.2em;') b.appendChild(img) const span = dom.createElement('span') span.innerHTML = 'New ' + classLabel b.appendChild(span) b.addEventListener( 'click', function (_event) { b.disabled = true container.appendChild(Object(_newIssue__WEBPACK_IMPORTED_MODULE_4__["newIssueForm"])(dom, kb, tracker, null, showNewIssue)) }, false ) // Table of issues - when we have the main issue list // We also need the ontology loaded // context.session.store.fetcher .load([stateStore]) .then(function (_xhrs) { const tableDiv = renderTabsTableAndBoard(tracker) // const tableDiv = renderTable(tracker) // was paneDiv.appendChild(tableDiv) if (tableDiv.refresh) { // Refresh function } else { console.log('No table refresh function?!') } paneDiv.appendChild(Object(_newTracker__WEBPACK_IMPORTED_MODULE_3__["newTrackerButton"])(subject)) updater.addDownstreamChangeListener(stateStore, tableDiv.refresh) // Live update }) .catch(function (err) { return console.log('Cannot load state store: ' + err) }) // end of Tracker instance } // render tracker /* Render tabs with both views */ const boardView = ns.wf('BoardView') const tableView = ns.wf('TableView') const settingsView = ns.wf('SettingsView') const instancesView = ns.wf('InstancesView') const updater = kb.updater const t = kb.findTypeURIs(subject) let tracker // Whatever we are rendering, lets load the ontology const flowOntology = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('').doc() if (!kb.holds(undefined, undefined, undefined, flowOntology)) { // If not loaded already $rdf.parse(__webpack_require__(/*! ./wf.js */ "./node_modules/issue-pane/wf.js"), kb, flowOntology.uri, 'text/turtle') // Load ontology directly } const userInterfaceOntology = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].ui('').doc() if (!kb.holds(undefined, undefined, undefined, userInterfaceOntology)) { // If not loaded already $rdf.parse(__webpack_require__(/*! ./ui.js */ "./node_modules/issue-pane/ui.js"), kb, userInterfaceOntology.uri, 'text/turtle') // Load ontology directly } // Render a single issue if ( t['http://www.w3.org/2005/01/wf/flow#Task'] || kb.holds(subject, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].wf('tracker')) ) { tracker = kb.any(subject, ns.wf('tracker')) if (!tracker) throw new Error('This issue ' + subject + 'has no tracker') // Much data is in the tracker instance, so wait for the data from it context.session.store.fetcher .load(tracker.doc()) .then(function (_xhrs) { const stateStore = kb.any(tracker, ns.wf('stateStore')) context.session.store.fetcher.nowOrWhenFetched( stateStore, subject, function drawIssuePane2 (ok, body) { if (!ok) { return console.log( 'Failed to load state ' + stateStore + ' ' + body ) } paneDiv.appendChild(Object(_issue__WEBPACK_IMPORTED_MODULE_2__["renderIssue"])(subject, context)) updater.addDownstreamChangeListener(stateStore, function () { solid_ui__WEBPACK_IMPORTED_MODULE_0__["widgets"].refreshTree(paneDiv) }) // Live update } ) }) .catch(err => { const msg = 'Failed to load config ' + tracker.doc() + ' ' + err return complain(msg) }) context.session.store.fetcher.nowOrWhenFetched( tracker.doc(), subject, function drawIssuePane1 (ok, body) { if (!ok) { return console.log( 'Failed to load config ' + tracker.doc() + ' ' + body ) } } ) // End nowOrWhenFetched tracker // ///////////////////////////////////////////////////////// // // Render a Tracker instance // } else if (t['http://www.w3.org/2005/01/wf/flow#Tracker']) { renderTracker().then(() => console.log('Tracker rendered')) } else { console.log( 'Error: Issue pane: No evidence that ' + subject + ' is either a bug or a tracker.' ) } let loginOutButton const overlay = paneDiv.appendChild(dom.createElement('div')) context.overlay = overlay overlay.style = OVERFLOW_STYLE overlay.style.visibility = 'hidden' // var overlayPane = null // overlay.appendChild(dom.createElement('div')) // avoid stomping on style by pane solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].checkUser().then(webId => { if (webId) { console.log('Web ID set already: ' + webId) context.me = webId // @@ enable things return } loginOutButton = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].loginStatusBox(dom, webIdUri => { if (webIdUri) { context.me = kb.sym(webIdUri) console.log('Web ID set from login button: ' + webIdUri) paneDiv.removeChild(loginOutButton) // enable things } else { context.me = null } }) loginOutButton.setAttribute('style', 'margin: 0.5em 1em;') paneDiv.appendChild(loginOutButton) if (!context.statusArea) { context.statusArea = paneDiv.appendChild(dom.createElement('div')) } }) return paneDiv } }); // ends /***/ }), /***/ "./node_modules/issue-pane/newIssue.js": /*!*********************************************!*\ !*** ./node_modules/issue-pane/newIssue.js ***! \*********************************************/ /*! exports provided: newIssueForm */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "newIssueForm", function() { return newIssueForm; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); // Form to collect data about a New Issue // const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] function newIssueForm (dom, kb, tracker, superIssue, showNewIssue) { const form = dom.createElement('div') // form is broken as HTML behaviour can resurface on js error const stateStore = kb.any(tracker, ns.wf('stateStore')) const timestring = function () { const now = new Date() return '' + now.getTime() // http://www.w3schools.com/jsref/jsref_obj_date.asp } const sendNewIssue = function () { titlefield.setAttribute('class', 'pendingedit') titlefield.disabled = true const sts = [] let issue const expandTemplate = function (template) { const now = new $rdf.Literal(new Date()) const nnnn = '' + new Date().getTime() const YYYY = now.value.slice(0, 4) const MM = now.value.slice(5, 7) const DD = now.value.slice(8, 10) return template .replace('{N}', nnnn) .replace('{YYYY}', YYYY) .replace('{MM}', MM) .replace('{DD}', DD) } // Where to store the new issue? let template = kb.anyValue(tracker, ns.wf('issueURITemplate')) let issueDoc if (template) { // Does each issue do in its own file? template = $rdf.uri.join(template, stateStore.uri) // Template is relative issue = kb.sym(expandTemplate(template)) } else { issue = kb.sym(stateStore.uri + '#' + 'Iss' + timestring()) } // eslint-disable-next-line prefer-const issueDoc = issue.doc() // Basic 9 core predicates are stored in the main stateStore const title = kb.literal(titlefield.value) sts.push(new $rdf.Statement(issue, ns.wf('tracker'), tracker, stateStore)) sts.push(new $rdf.Statement(issue, ns.dc('title'), title, stateStore)) sts.push( new $rdf.Statement(issue, ns.dct('created'), new Date(), stateStore) ) const initialStates = kb.each(tracker, ns.wf('initialState')) if (initialStates.length === 0) { console.log('This tracker has no initialState') } for (let i = 0; i < initialStates.length; i++) { sts.push( new $rdf.Statement( issue, ns.rdf('type'), initialStates[i], stateStore ) ) } if (superIssue) { sts.push( new $rdf.Statement(superIssue, ns.wf('dependent'), issue, stateStore) ) } // Other things are stores in the individual if (template) { sts.push(new $rdf.Statement(issue, ns.wf('tracker'), tracker, issueDoc)) sts.push( new $rdf.Statement(issue, ns.rdfs('seeAlso'), stateStore, issueDoc) ) } const sendComplete = function (uri, success, body) { if (!success) { console.log("Error: can't save new issue:" + body) } else { form.parentNode.removeChild(form) showNewIssue(issue) } } kb.updater.update([], sts, sendComplete) } const states = kb.any(tracker, ns.wf('issueClass')) const classLabel = solid_ui__WEBPACK_IMPORTED_MODULE_0__["utils"].label(states) form.innerHTML = '

Add new ' + (superIssue ? 'sub ' : '') + classLabel + '

Title of new ' + classLabel + ':

' var titlefield = dom.createElement('input') titlefield.setAttribute('type', 'text') titlefield.setAttribute( 'style', 'margin: 0.5em; font-size: 100%; padding: 0.3em;' ) titlefield.setAttribute('size', '100') titlefield.setAttribute('maxLength', '2048') // No arbitrary limits titlefield.select() // focus next user input titlefield.addEventListener( 'keyup', function (e) { if (e.keyCode === 13) { sendNewIssue() } }, false ) form.appendChild(titlefield) return form } /***/ }), /***/ "./node_modules/issue-pane/newTracker.js": /*!***********************************************!*\ !*** ./node_modules/issue-pane/newTracker.js ***! \***********************************************/ /*! exports provided: newTrackerButton */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "newTrackerButton", function() { return newTrackerButton; }); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-ui */ "./node_modules/solid-ui/lib/index.js"); /* harmony import */ var solid_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(solid_ui__WEBPACK_IMPORTED_MODULE_0__); const $rdf = solid_ui__WEBPACK_IMPORTED_MODULE_0__["rdf"] const ns = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"] const kb = solid_ui__WEBPACK_IMPORTED_MODULE_0__["store"] const updater = kb.updater /* Button for making a whole new tracker ** This is the least tesetd part of the tracker system at the moment. */ function newTrackerButton (thisTracker, context) { function timestring () { const now = new Date() return '' + now.getTime() // http://www.w3schools.com/jsref/jsref_obj_date.asp } // const dom = context.dom const button = solid_ui__WEBPACK_IMPORTED_MODULE_0__["authn"].newAppInstance(context.dom, { noun: 'tracker' }, function ( ws, base ) { const appPathSegment = 'issuetracker.w3.org' // how to allocate this string and connect to // console.log("Ready to make new instance at "+ws) const sp = solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].space const kb = context.session.store if (!base) { base = kb.any(ws, sp('uriPrefix')).value if (base.slice(-1) !== '/') { $rdf.log.error( appPathSegment + ': No / at end of uriPrefix ' + base ) base = base + '/' } base += appPathSegment + '/' + timestring() + '/' // unique id if (!confirm('Make new tracker at ' + base + '?')) { return } } const stateStore = kb.any(thisTracker, ns.wf('stateStore')) const newStore = kb.sym(base + 'store.ttl') const here = thisTracker.doc() const oldBase = here.uri.slice(0, here.uri.lastIndexOf('/') + 1) var morph = function (x) { // Move any URIs in this space into that space if (x.elements !== undefined) return x.elements.map(morph) // Morph within lists if (x.uri === undefined) return x let u = x.uri if (u === stateStore.uri) return newStore // special case if (u.slice(0, oldBase.length) === oldBase) { u = base + u.slice(oldBase.length) $rdf.log.debug(' Map ' + x.uri + ' to ' + u) } return kb.sym(u) } const there = morph(here) const newTracker = morph(thisTracker) const myConfig = kb.statementsMatching( undefined, undefined, undefined, here ) for (let i = 0; i < myConfig.length; i++) { const st = myConfig[i] kb.add( morph(st.subject), morph(st.predicate), morph(st.object), there ) } // Keep a paper trail @@ Revisit when we have non-public ones @@ Privacy // kb.add(newTracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].space('inspiration'), thisTracker, stateStore) kb.add(newTracker, solid_ui__WEBPACK_IMPORTED_MODULE_0__["ns"].space('inspiration'), thisTracker, there) // $rdf.log.debug("\n Ready to put " + kb.statementsMatching(undefined, undefined, undefined, there)); //@@ updater.put( there, kb.statementsMatching(undefined, undefined, undefined, there), 'text/turtle', function (uri2, ok, message) { if (ok) { updater.put(newStore, [], 'text/turtle', function ( uri3, ok, message ) { if (ok) { console.info( 'Ok The tracker created OK at: ' + newTracker.uri + '\nMake a note of it, bookmark it. ' ) } else { console.log( 'FAILED to set up new store at: ' + newStore.uri + ' : ' + message ) } }) } else { console.log( 'FAILED to save new tracker at: ' + there.uri + ' : ' + message ) } } ) // Created new data files. // @@ Now create initial files - html skin, (Copy of mashlib, css?) // @@ Now create form to edit configuation parameters // @@ Optionally link new instance to list of instances -- both ways? and to child/parent? // @@ Set up access control for new config and store. }) // callback to newAppInstance button.setAttribute('style', 'margin: 0.5em 1em;') return button } // newTrackerButton /***/ }), /***/ "./node_modules/issue-pane/trackerSettingsForm.js": /*!********************************************************!*\ !*** ./node_modules/issue-pane/trackerSettingsForm.js ***! \********************************************************/ /*! exports provided: trackerSettingsFormText */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "trackerSettingsFormText", function() { return trackerSettingsFormText; }); const trackerSettingsFormText = ` @prefix : . @prefix core: . @prefix dct: . @prefix owl: . @prefix rdfs: . @prefix ui: . @prefix vcard: . @prefix wf: . core:TrackerSettingsForm a :Form; "Tracker Configuration Form"; :parts ( [ a ui:Heading; ui:contents "About the tracker"@en ] [ a :SingleLineTextField; :label "Title of issue tracker"; :maxLength "128"; :property dct:title; :size "40" ] [ a :MultiLineTextField; :label "Description"; :property wf:description; :size "40" ] [ a ui:Choice; ui:canMintNew true; ui:use core:SuperClassForm; ui:follow true; ui:property wf:issueClass; ui:label "What states can an issue be in?"; ui:from rdfs:Class; ui:default wf:Task ] [ a ui:Comment; ui:contents """You can optionally sort issues using (one or more) classification systems"""@en ] [ a ui:Choice; ui:canMintNew true; ui:use core:ClassificationForm; ui:property wf:issueCategory; ui:label "Sort them into which category?"; ui:from rdfs:Class ] [ a :BooleanField; :label "Allow issues to have sub-issues"; :property wf:allowSubIssues; :default false ] [ a ui:Heading; ui:contents "Table view:"@en ] [ a ui:Comment; ui:contents "Any extra properties to include?"@en ] [a ui:Multiple; ui:property wf:propertyList; ui:ordered true; ui:part core:PropertyForm; ui:follow true ] [ a ui:Heading; ui:contents "Details of issues"@en ] # Use a people picker ideally [ a ui:Choice; ui:canMintNew true; ui:use core:GroupForm; ui:property wf:assigneeGroup; ui:label "Assign issues to people from which group?"; ui:from vcard:Group; ] # Optionally one form for extras [ a ui:Choice; ui:canMintNew true; ui:use ui:FormForm; ui:property wf:extrasEntryForm; ui:label "Other things to save about each issue?"; ui:from ui:Form; ] ) . # Form for the superclass of all states # @@ also We must require each state class to be stated to be a subclass of EITHER Open OR Closed. core:SuperClassForm a ui:Form; dct:title "Form for managing states"; ui:parts ( [ a :SingleLineTextField; :label "Name of set of states"; :defualt "States"; :maxLength "128"; :property rdfs:label; :size "40" ] [a ui:Multiple; ui:property owl:disjointUnionOf; ui:ordered true; ui:part core:StateForm ] # [ a ui:Multiple; ui:property rdfs:subClassOf; ui:reverse true; ui:part core:StateForm ] ) . core:StateForm a ui:Form; dct:title "Form for one state"; ui:parts ( [ a :SingleLineTextField; :label "Name of state"; :maxLength "128"; :property rdfs:label; :size "40" ] [ a :ColorField; :label "Background color"; :property :backgroundColor ] # @@ add icon for state ). # Form for Classification core:ClassificationForm a ui:Form; dct:title "Form for a classification by categpry"; ui:parts ( [ a :SingleLineTextField; :label "Name of classification:"; :maxLength "128"; :property rdfs:label; :size "40" ] [a ui:Multiple; ui:property owl:disjointUnionOf; ui:ordered true; ui:part core:CategoryForm ] ) . core:CategoryForm a ui:Form; dct:title "Form for a category"; ui:parts ( [ a :SingleLineTextField; :label "Name of category"; :maxLength "128"; :property rdfs:label; :size "40" ] [ a :ColorField; :label "Background color"; :property :backgroundColor ] ). core:PropertyForm a ui:Form; ui:parts ( # Internded for raed only only marking the [ a :SingleLineTextField; :label "(property name)"; :maxLength "128"; :property rdfs:label; :size "40" ] ). # Other ontology stuff we are otherwis missing # we can usde ui:label to give a decent abel when the ontology uses a really bad one rdfs:subClassOf ui:label "super class" . # We can also add a specific nice label for the inverse [] owl:inverse rdfs:subClassOf; rdfs:label "sub class" . owl:disjointUnionOf ui:label "option" . # Form for new group core:GroupForm a ui:Form; dct:title "Form for new contacts group"; ui:parts ( [ a :SingleLineTextField; :label "Name of new group"; :maxLength "128"; :property vcard:fn; :size "60" ] [ a ui:Heading; ui:contents "Members of group"@en ] [ a ui:Multiple; ui:label "contacts in group"; ui:property vcard:member; ui:part core:PersonForm ] ). core:PersonForm a ui:Form; dct:title "New contact details form"; ui:parts ( [ a :NamedNodeURIField; ui:label "Solid ID"; ui:property owl:sameAs; ui:size 60 ] [ a :SingleLineTextField; :label "Name of contact"; :maxLength "128"; :property vcard:fn; :size "60" ] [ a ui:PhoneField; :label "Phone"; :property vcard:phone; ] # @@ check property] [ a :EmailField; :label "Email"; :property vcard:email ] # @@ check property ). # classificattion owl:disjointUnionOf () wf:Tracker :creationForm core:SettingsForm . ` /***/ }), /***/ "./node_modules/issue-pane/ui.js": /*!***************************************!*\ !*** ./node_modules/issue-pane/ui.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = ` # Ontology for user interface hints and forms # # See also related: the Fresnel language # @prefix contact: . @prefix dc: . @prefix doc: . @prefix foaf: . @prefix owl: . @prefix r: . @prefix s: . @prefix tt: . @prefix ui: . @prefix : . @prefix wf: . @prefix xsd: . @keywords is, of, a. <> dc:title "An ontology for User Interface description, Hints and Forms."; dc:description """The User Interface ontology allows the definition of forms for processing RDF model data, and include a bootstrap form for editing forms. It allows user interface hints such as background colors, can be associated with objects and classes. """; dc:created 2010-08-07; dc:license ; dc:modified """$Date: 2020/03/22 16:53:21 $"""; dc:author . style a r:Property, owl:DatatypeProperty; s:label "style"; prompt "CSS style"; s:comment """Must be a valid CSS style string such as one could put in an HTML style attribute. Depending on the user interface system, this can by given to individuals, classes or properties. It is up to a user interface which wants to draw on them to pick how it uses styles from which parts of the data it has. For example, the style of a class may be picked to distinguish information about things in that class.""". backgroundColor a r:Property, owl:DatatypeProperty; s:label "background color"@en; s:range ui:Color; s:comment """Must be a valid CSS color string such as one could put in an HTML style attribute. This should be in the #xxxxxx form, (with 6 digits of hex) so that it can work with Graphviz.""". backgroundImage a r:Property, owl:DatatypeProperty; s:label "background image"@en; s:comment """URI or base64 representation of an image""". color a r:Property, owl:DatatypeProperty; s:label "color"@en; s:range ui:Color; s:comment """Must be a valid CSS color string such as one could put in an HTML style attribute. This should be in the #xxxxxx form, (with 6 digits of hex) so that it can work with Graphviz.""". sortPriority a r:Property, owl:DatatypeProperty; s:label "sort priority"; s:range xsd:integer; s:comment """When individuals or classes must be sorted, then if they are given different values of sortPriority a user agent can use this as a hint to how to present information.""". sortBy a r:Property; s:label "sort by"; s:domain s:Class; s:range r:Property; s:comment """A property which typically is used to sort members of a given class.""". seqeunce a r:Property; s:label "sequence number"; s:range xsd:integer; s:comment """The sequence in which this item is arranged with repect to other parts.""". initialProperties a r:Property; s:label "initial properties"; s:domain s:Class; s:range r:List; # List of r:Property s:comment """A really simple way of enabling user interfaces to create new information about a class of things is to make a define of properties to be specified when a information about a new item ("New item" here means an item which the system does not have prvious information about yet, not an items which has just been created, like new friend as opposed to new baby)"""; prompt "Properties to be specified for new ones". tableProperties a r:Property; s:domain s:Class; s:label "table properties"; s:range r:List; # List of r:Property s:comment """This is a crude way of specifying a table-based view for objects of this class."""; prompt "Properties to be given in a default table view". prompt a r:Property; s:label "user prompt"; s:comment """A string for the UI to use if the user needs a longer prompts than just a field name, the rdfs:label. """; ui:prompt "A longer prompt for a user inputting this property". # A Taxonomy of Field types ui:Form owl:disjointUnionOf ( ui:ValueField ui:Group ui:Choice ui:Classifier ui:Options ui:Multiple ui:Heading ui:Comment); s:comment """A form can be any type of single field, or typically a Group of several fields, including interspersed headings and comments. """. ui:Single owl:disjointUnionOf ( ui:ValueField ui:Group ui:Choice ui:Classifier ui:Options ui:Heading ui:Comment). ui:ValueField owl:disjointUnionOf ( ui:TextField ui:NumericField ui:ColorField ui:DateField ui:DateTimeField ui:PhoneField ui:EmailField). ui:NumericField owl:disjointUnionOf (ui:BooleanField ui:TriStateField ui:IntegerField ui:DecimalField ui:FloatField). # ui:Multiple owl:disjointUnionOf ( ui:ZeroOrMore ui:OneOrMore ). ui:TextField owl:disjointUnionOf (ui:SingleLineTextField ui:MultiLineTextField). ui:Form a s:Class; is s:subClassOf of ui:ValueField, ui:Group, ui:Choice, ui:Heading, ui:Comment, ui:Classifier, ui:Options, ui:Multiple. ui:Single a s:Class; is s:subClassOf of ui:ValueField, ui:Group, ui:Choice, ui:Heading, ui:Comment, ui:Classifier, ui:Options. ui:ValueField a s:Class; is s:subClassOf of ui:TextField, ui:NumericField, ui:ColorField, ui:DateField, ui:DateTimeField, ui:PhoneField, ui:EmailField. ui:NumericField a s:Class; is s:subClassOf of ui:BooleanField, ui:TriStateField, ui:IntegerField, ui:DecimalField, ui:FloatField. ui:TextField a s:Class; is s:subClassOf of ui:SingleLineTextField, ui:MultiLineTextField. ui:Classifier a s:Class; s:label "classifier"; s:comment """A classifier allows the user to select the type of an object. The possible types must be subclasses of some overall class, the "category". (Ideally, the superclass is also set up as the disjoint union of the subclasses, if they are disjoint.) The form normally stores the resulting classes using an rdf:type triple, but a different predicate can be used if required, so the classifier field needs is 'property' defined too. If the subclass selected itself is has subclasses defined, the user can recursively select from them in turn, as many levels as needed.""". ui:property a r:Property; s:domain ui:Form; s:range r:Property; s:label "property to be stored"@en; s:comment """Many fields prompt for information about a given property of the subject. When field is filled in, this gives which property is written into the data.""". ui:category a r:Property; s:domain ui:Classifier; s:range s:Class; s:label "overall superclass"@en; s:comment """The superclass subclasses of which will be selected.""". ui:dependingOn a r:Property; s:domain ui:Options; s:range r:Property; s:label "depending on"@en; s:comment """Many fields prompt for information about a given property of the subject""". ui:for a r:Property; s:label "for"@en; s:comment "The value for which this case is selected.". ui:use a r:Property; s:range ui:Form. ui:part a r:Property; s:label "part"@en ; s:domain ui:Form; s:range ui:Form. # Used for Multiple field - the subform for each item ui:parts a r:Property; s:label "parts"@en ; s:domain ui:Form; s:range r:Collection. # (of Forms) The ordered set of fields in a group ui:ordered e r:Property; s:label "ordered"; s:range xsd:Boolean . # Could be useful for all kinds of things in future so not restricted to Multiple ui:from a r:Property; s:domain ui:Choice; s:range r:Class; s:label "from"; ui:prompt "from what class". ui:size a r:Property; s:domain ui:ValueField; s:range xsd:integer; s:label "size of field"; ui:prompt "size of field in characters". ui:maxLength a r:Property; s:domain ui:TextField; s:range xsd:integer; s:label "max length of value". ui:minValue a r:Property; s:domain ui:ValueField; s:label "min". # @@ range? ui:maxValue a r:Property; s:domain ui:ValueField; s:label "max". ui:creationForm a r:Property; s:domain s:Class; s:range ui:Form; s:label "creation form"; s:comment """A form which may be used to collect information about a hitherto locally undocumented instance instance of this class.""". ui:annotationForm a r:Property; s:domain s:Class; s:range ui:Form; s:label "annotation form"; s:comment """A form which may be used to add more infromation to an instance of this class which we know something about. Anything from adding just add one more fact, to adding a whole lot of information about a specific facet of the thing. """. ############################################# # # Form for editing Forms # FormForm a ui:Form; dc:title "Form for editing Forms"; is ui:creationForm of Form; a ui:Group; ui:parts (FF1 FF2 FF3 FieldList) . FF1 ui:sequence 1; a ui:Heading; ui:contents "Edit Form"@en . FF2 ui:sequence 2; a ui:SingleLineTextField; ui:property dc:title; ui:size 60 . FF3 ui:sequence 3; a ui:Comment; ui:contents """To add a field to the form, press the plus at the bottom, and then select what sort of field you want."""@en; ui:style "background-color: #ffe;" . FieldList ui:sequence 10; a ui:Multiple; ui:ordered true; ui:property ui:parts; ui:part FieldForm . FieldForm a ui:Group; dc:title "Form for selecting a type of field"; ui:parts ( [ ui:sequence 1; a ui:Classifier; ui:property r:type; ui:category ui:Form] [ a ui:Options; ui:sequence 2; ui:dependingOn r:type; ui:case [ ui:for ui:TextField; ui:use [a ui:Group; ui:parts ( [ a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] # @@@ Needs inference on current web [ a ui:IntegerField; ui:property ui:size; ui:label "field size"; ui:min 1; ui:max 4096] [ a ui:IntegerField; ui:property ui:maxLength; ui:label "Max. length of string"; ui:min 1] )]]; ui:case [ ui:for ui:IntegerField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] [ ui:sequence 2; a ui:IntegerField; ui:property ui:min; ui:label "minimum value"] [ ui:sequence 3; a ui:IntegerField; ui:property ui:max; ui:label "maximum value"] ) ]]; ui:case [ ui:for ui:DecimalField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] [ ui:sequence 2; a ui:DecimalField; ui:property ui:min; ui:label "minimum value"] [ ui:sequence 3; a ui:DecimalField; ui:property ui:max; ui:label "maximum value"] ) ]]; ui:case [ ui:for ui:FloatField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] [ ui:sequence 2; a ui:FloatField; ui:property ui:min; ui:label "minimum value"] [ ui:sequence 3; a ui:FloatField; ui:property ui:max; ui:label "maximum value"] ) ]]; ui:case [ ui:for ui:ColorField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] ) ]]; ui:case [ ui:for ui:DateField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] [ ui:sequence 2; a ui:DateField; ui:property ui:min; ui:label "min"] [ ui:sequence 3; a ui:DateField; ui:property ui:max ; ui:label "max"] ) ]]; ui:case [ ui:for ui:DateTimeField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:DatatypeProperty] [ ui:sequence 2; a ui:DateTimeField; ui:property ui:min; ui:label "min"] [ ui:sequence 3; a ui:DateTimeField; ui:property ui:max ; ui:label "max"] ) ]]; ui:case [ ui:for ui:EmailField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:ObjectProperty] ) ]]; ui:case [ ui:for ui:PhoneField; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:ObjectProperty] )]]; ui:case [ ui:for ui:Group; ui:use FieldList]; ui:case [ ui:for ui:Options; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:dependingOn; ui:label "depending on"; ui:from r:Property; ui:default r:type] [ ui:sequence 2; a ui:Multiple; ui:property ui:case; ui:part CaseForm] ) ]]; ui:case [ ui:for ui:Choice; ui:use [a ui:Group; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:canMintNew true; ui:from owl:ObjectProperty] [ ui:sequence 2; a ui:Choice; ui:canMintNew true; ui:property ui:from; ui:label "destination class"; ui:from s:Class; ui:canMintNew true; ] [ ui:sequence 3; a ui:BooleanField; ui:property ui:canMintNew; # No class form yet ui:label "user can add new"] [ ui:sequence 4; a ui:Choice; ui:canMintNew true; ui:property ui:use; ui:label "Nested Form (if any)"; ui:from ui:Form; ui:optional true; ui:use FormForm] # @@ optional ) ]]; ui:case [ ui:for ui:Classifier; ui:use [a ui:Group; ui:parts ( [ ui:sequence 2; a ui:Comment; ui:contents """A classifier allows the user to which classes the item belongs to, given a common superclass of the allowed classes. Give the superclass here:""" ] [ ui:sequence 4; a ui:Choice; ui:canMintNew true; ui:property ui:category; ui:label "superclass"; ui:from s:Class] [ ui:sequence 6; a ui:Comment; ui:contents """(When the choice is made normally the item is given a rdf:type. Set this to rdf:type unless you want the form to set a different property.)""" ] [ ui:sequence 8; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from owl:ObjectProperty; ui:default r:type] # @@ restriction ) ]]; ui:case [ ui:for ui:Multiple; ui:use [a ui:Group; ui:parts ( [ui:sequence 0; a ui:BooleanField; ui:property ui:ordered; ui:label "ordered"] # If this an ordered array or an unordered set? [ui:sequence 0; a ui:IntegerField; ui:property ui:min; ui:label "minimum number"] # If this an ordered array or an unordered set? [ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:property; ui:label "property"; ui:from r:Property] [ui:sequence 2; a ui:Choice; ui:canMintNew true; ui:property ui:part; ui:from ui:Form; ui:use FieldForm] # Form for details of the field part of the multiple ) ]]; ui:case [ ui:for ui:Heading; ui:use [a ui:SingleLineTextField; ui:property ui:contents]]; ui:case [ ui:for ui:Comment; ui:use [a ui:MultiLineTextField; ui:property ui:contents]] ]). CaseForm a ui:Group; dc:title "Form for a conditional case in a form"; ui:parts ( [ ui:sequence 1; a ui:Choice; ui:canMintNew true; ui:property ui:for; ui:label "when it is"; ui:canMintNew true; ui:from s:Class] [ui:sequence 2; a ui:Choice; ui:canMintNew true; ui:property ui:use; ui:from ui:Form; ui:canMintNew true; ui:use FieldForm] ). # Form for details of the field part of the multiple # ENDS ` /***/ }), /***/ "./node_modules/issue-pane/wf.js": /*!***************************************!*\ !*** ./node_modules/issue-pane/wf.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = ` # Issue tracking - Workflow application definition ontology # # Finite state automaton ontology # # See requirements for tracking tools http://www.w3.org/2005/01/06-tool-req.html # @keywords a, is, of. @prefix : . @prefix wf: . @prefix rdf: . @prefix s: . @prefix owl: . @prefix xsd: . @prefix doc: . @prefix log: . @prefix foaf: . @prefix contact: . @prefix doap: . @prefix dc: . @prefix dct: . @prefix ui: . <> dc:title "Issue Tracking Ontology"; dct:creator ; s:comment """This ontology defines a very general class (Task) which can used for any kind of bug tracking, issue tracking, to-do-list management, action items, goal dependency, and so on. It captures the state of a task as a subclass, so that subsumption can be used. It captures a discussion thread about a task. It captures subtasks structure if necessary. A "Tracker" defines actual set of states, categories, etc., which a task can be in. The data about the tracker guides the software managing the task. There is some workflow modeling finite state machine terms which are optional for more complex definition of the transitions allowed. """. Task a s:Class; s:label "task"@en; owl:disjointUnionOf (Open Closed); s:comment """Something to be done in a wide sense, an agenda item at a meeting is one example, but any issue, task, action item, goal, product, deliverable, milestone, can such a thing. The requirement for this framework was that it would allow one to customize ontologies for things such as agenda items, action items, working group issues with a spec, w3c Last Call issues, software bugs and administrative requests. In π-calculus, a process. Make your type of issue a subclass of Task. """. Open a s:Class; s:subClassOf Task; s:label "open"@en, "ouvert"@fr; ui:backgroundColor "#d6f5d6"; # green like github for some reason s:comment """A task which needs attention. The very crude states of Open and Closed all interoperability between different systems if the states for a given application are made subclasses of either Open or Closed. This allows tasks from different systems to be mixed and treated together with limited but valuable functionality. """. Closed a s:Class; s:subClassOf Task; s:label "closed"@en, "fermé"@fr; ui:backgroundColor "#f5d6d6"; # pink s:comment """A task which does not need attention. It may be closed because has been abandoned or completed, for example. """. ActionItem a s:Class; s:subClassOf Task; s:label "action item"@en; owl:disjointUnionOf (Open Closed); s:comment """An obligation taken on by a person, typically at a meeting. """. description a rdf:Property; s:label "description"; s:comment """The description, definition, or abstract. Information explaining what this is. Not arbitrary comment about anything, only about the subject. (Use this property for anything. There is no domain restriction.).""". dependent a rdf:Property; s:label "how"; owl:inverseOf [ s:label "why"]; s:domain Task; s:range Task; s:comment """Another task upon which this depends, in the sense that this task cannot be completed without that task being done. You can't use this for dependencies on anything other than other tasks. (Note the US spelling of the URI. In the UK, a dependant is a something which is dependent on somehing else.)""". assignee a rdf:Property; s:label "assigned to"; owl:inverseOf [s:label "assignment"]; # s:domain Task; s:range foaf:Agent; s:comment """The person or group to whom this has been assigned.""". # use dct:modified #modified a rdf:Property; # s:label "last changed". modifiedBy a rdf:Property; s:range foaf:Agent; s:label "changed by". # use dct:created instead #created a rdf:Property; # s:range xsd:dateTime; # # Use foaf:maker instead #creator a rdf:Property; # s:range foaf:Agent; # s:label "changed by". subscriber a rdf:Property; s:label "subscriber"; s:range foaf:Agent. ################## Products # # # History: The Tracker system included a cocept of a product, # such that an action could be associated with *either* an issue *or* a product. # Noah Mendelsohn for the TAG needed to be able make # and to give products: Goals, scuuess criteria, # deliverables with dates, schedules, TAG members assigned, related issues. # Product a s:Class; s:subClassOf Task; s:label "product"; s:comment """A product is a task which monitors something which must be produced.""". deliverable a rdf:Property; s:subPropertyOf dependent; s:range Product; s:label "deliverable"@en; s:comment """Something which must be delivered to accomplish this""". goalDescription a rdf:Property, owl:DatatypeProperty; s:domain Task; s:range xsd:string; s:label "goals"; s:comment """A textual description of the goals of this product, etc.""". successCriteria a rdf:Property, owl:DatatypeProperty; s:domain Task; s:range xsd:string; s:label "success criteria"; s:comment """A textual description of the successs critera. How when we know this is done?""". dateDue a rdf:Property, owl:DatatypeProperty; s:domain Task; s:range xsd:date; s:label "due"@en; s:comment """The date this task is due. """. ################## Attachments attachment a rdf:Property; s:label "attachment"; s:comment """Something related is attached for information.""". screenShot a rdf:Property; s:subPropertyOf attachment; s:label "screen shot"@en; s:comment """An image taken by capturing the state of a computer screen, for example to demonstrate a problem""". testData a rdf:Property; s:subPropertyOf attachment; s:label "test data"@en; s:comment """A file which can be used as inpiut to a test or to demonstrate a problem. """. terminalOutput a rdf:Property; s:subPropertyOf attachment; s:label "terminal output"@en; s:comment """A file showing user interaction from a text terminal or console etc. """. message a rdf:Property; s:subPropertyOf attachment; s:label "message"@en; s:comment """A message about this. Attached for information.""". Message a s:Class; s:label "message"@en. recipent a rdf:Property; s:label "to"; s:domain Message; s:range foaf:Agent. sender a rdf:Property; s:label "from"; s:domain Message; s:range foaf:Agent. ############################# A Tracker connects and manages issues tracker a rdf:Property; s:label "tracker"; owl:inverseOf [ s:label "issue"]; s:domain Task; s:range Tracker. Tracker a s:Class; s:label "tracker"; s:comment """A set of issues and the constraints on how they evolve. To use this ontology, craete a new tracker. Copy an existing one or make up your own.""". issueClass a rdf:Property; s:label "all issues must be in"; s:domain Tracker; s:range s:Class, State; s:comment """The class of issues which are allowed in this tracker. This is essemtial to the operation of the tracker, as it defines which states an issue can be in. (The issueClass must be a disjointUnionOf the state classes)""". issueCategory a rdf:Property; s:label "issue category"; s:domain Tracker; s:range s:Class; s:comment """Issues may be categorized according to the subclasses of this class""". stateStore a rdf:Property; s:label "state store"; s:domain Tracker; s:range doc:Document; s:comment """A read-write document. The state of the issues is modified here. When you set up a trcaker, thgis must be set to point to a writeble data resource on the web.""". transactionStore a rdf:Property; s:label "transaction store"; s:domain Tracker; s:range doc:Document; s:comment """An appendable document. Transactions and messsages can be written into here""". asigneeClass a rdf:Property; s:label "assignees must be"; s:domain Tracker; s:range s:Class; # Subclass of foaf:Agent s:comment """When an issue is assigned, the assignee must be from this class""". initialState a rdf:Property; s:label "initial state"@en; s:label "état initial"@fr; s:domain Tracker; s:range State; s:comment """The initial state for a new issue""". # Use this to link a project to a tracker doap:bug-database owl:inverseOf [ s:label "project"@en ]. ############################################################ # # Finite state machines # Change a s:Class; s:label "change"; s:comment """The universal class of things which change the state of a task. Included now: Creation, Transition. (Maybe in the future more π-calculus constructions such as splitting & merging tasks, and import/export of obligations to a foreign opaque system.) """. Transition a s:Class; s:subClassOf Change; s:label "transition"; s:comment """A transition is a change of state of a task. Typical properties include date and/or source (a document causing the transition), and a final state.""". Creation a s:Class; s:subClassOf Change; s:label "creation"; s:comment """A creation is a change from existence to non-existence a task. Typical properties include date and/or source (a document causing the transition), and a final state.""". date s:range DateTime. final a rdf:Property; s:label "to"; s:domain Transition; s:range State. task a rdf:Property; s:range Task; s:label "task". requires a rdf:Property; s:label "requires"; s:domain Transition; s:range rdf:List; # Of properties for validation s:comment """To be a valid transition, a necessary (but not necessarily sufficuent) condition is that there be recorded these properties for the record""". affects a rdf:Property; s:label "affects"; s:domain doc:Work; s:range Task. # { ?x a Transition; task ?t; source ?doc } => { ?doc affects ?t }. creates a rdf:Property; s:label "creates"; s:domain doc:Work; s:range Task. allowedTransitions a rdf:Property; s:domain State; s:range rdf:List; # @@@ of Action s:label "allowed transitions"; s:comment """The state machine is defined by these lists of transition allowed for each issue. (An interesting option in the Web is to make an allowed transition to a state in soemone else's ontology, which in turn allows transitions into many ontologies. So a finite state maxchine may become very large. In practice this means that a task handed off to another organization may be processed on all kinds of ways.)""". # { ?x a TerminalState} => { ?x allowedTransitions () }. final a rdf:Property; s:label "to"; s:range State. issue a rdf:Property; s:label "issue"; s:comment """A transition changes the state of the given issue.""". source a rdf:Property; s:label "source"; s:comment """The source of a transition is the document by which it happened"""; s:range doc:Work. TerminalState a s:Class; s:subClassOf State; s:label "terminal state"; s:comment """A state from which there are no transitions.""". NonTerminalState a s:Class; s:label "non-terminal state"; owl:disjointWith TerminalState; s:comment """A state from which there are transitions.""". ###################################################### #ends ` /***/ }), /***/ "./node_modules/jsonld/lib/ContextResolver.js": /*!****************************************************!*\ !*** ./node_modules/jsonld/lib/ContextResolver.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2019 Digital Bazaar, Inc. All rights reserved. */ const { isArray: _isArray, isObject: _isObject, isString: _isString, } = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const { asArray: _asArray } = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const {prependBase} = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const ResolvedContext = __webpack_require__(/*! ./ResolvedContext */ "./node_modules/jsonld/lib/ResolvedContext.js"); const MAX_CONTEXT_URLS = 10; module.exports = class ContextResolver { /** * Creates a ContextResolver. * * @param sharedCache a shared LRU cache with `get` and `set` APIs. */ constructor({sharedCache}) { this.perOpCache = new Map(); this.sharedCache = sharedCache; } async resolve({ activeCtx, context, documentLoader, base, cycles = new Set() }) { // process `@context` if(context && _isObject(context) && context['@context']) { context = context['@context']; } // context is one or more contexts context = _asArray(context); // resolve each context in the array const allResolved = []; for(const ctx of context) { if(_isString(ctx)) { // see if `ctx` has been resolved before... let resolved = this._get(ctx); if(!resolved) { // not resolved yet, resolve resolved = await this._resolveRemoteContext( {activeCtx, url: ctx, documentLoader, base, cycles}); } // add to output and continue if(_isArray(resolved)) { allResolved.push(...resolved); } else { allResolved.push(resolved); } continue; } if(ctx === null) { // handle `null` context, nothing to cache allResolved.push(new ResolvedContext({document: null})); continue; } if(!_isObject(ctx)) { _throwInvalidLocalContext(context); } // context is an object, get/create `ResolvedContext` for it const key = JSON.stringify(ctx); let resolved = this._get(key); if(!resolved) { // create a new static `ResolvedContext` and cache it resolved = new ResolvedContext({document: ctx}); this._cacheResolvedContext({key, resolved, tag: 'static'}); } allResolved.push(resolved); } return allResolved; } _get(key) { // get key from per operation cache; no `tag` is used with this cache so // any retrieved context will always be the same during a single operation let resolved = this.perOpCache.get(key); if(!resolved) { // see if the shared cache has a `static` entry for this URL const tagMap = this.sharedCache.get(key); if(tagMap) { resolved = tagMap.get('static'); if(resolved) { this.perOpCache.set(key, resolved); } } } return resolved; } _cacheResolvedContext({key, resolved, tag}) { this.perOpCache.set(key, resolved); if(tag !== undefined) { let tagMap = this.sharedCache.get(key); if(!tagMap) { tagMap = new Map(); this.sharedCache.set(key, tagMap); } tagMap.set(tag, resolved); } return resolved; } async _resolveRemoteContext({activeCtx, url, documentLoader, base, cycles}) { // resolve relative URL and fetch context url = prependBase(base, url); const {context, remoteDoc} = await this._fetchContext( {activeCtx, url, documentLoader, cycles}); // update base according to remote document and resolve any relative URLs base = remoteDoc.documentUrl || url; _resolveContextUrls({context, base}); // resolve, cache, and return context const resolved = await this.resolve( {activeCtx, context, documentLoader, base, cycles}); this._cacheResolvedContext({key: url, resolved, tag: remoteDoc.tag}); return resolved; } async _fetchContext({activeCtx, url, documentLoader, cycles}) { // check for max context URLs fetched during a resolve operation if(cycles.size > MAX_CONTEXT_URLS) { throw new JsonLdError( 'Maximum number of @context URLs exceeded.', 'jsonld.ContextUrlError', { code: activeCtx.processingMode === 'json-ld-1.0' ? 'loading remote context failed' : 'context overflow', max: MAX_CONTEXT_URLS }); } // check for context URL cycle // shortcut to avoid extra work that would eventually hit the max above if(cycles.has(url)) { throw new JsonLdError( 'Cyclical @context URLs detected.', 'jsonld.ContextUrlError', { code: activeCtx.processingMode === 'json-ld-1.0' ? 'recursive context inclusion' : 'context overflow', url }); } // track cycles cycles.add(url); let context; let remoteDoc; try { remoteDoc = await documentLoader(url); context = remoteDoc.document || null; // parse string context as JSON if(_isString(context)) { context = JSON.parse(context); } } catch(e) { throw new JsonLdError( 'Dereferencing a URL did not result in a valid JSON-LD object. ' + 'Possible causes are an inaccessible URL perhaps due to ' + 'a same-origin policy (ensure the server uses CORS if you are ' + 'using client-side JavaScript), too many redirects, a ' + 'non-JSON response, or more than one HTTP Link Header was ' + 'provided for a remote context.', 'jsonld.InvalidUrl', {code: 'loading remote context failed', url, cause: e}); } // ensure ctx is an object if(!_isObject(context)) { throw new JsonLdError( 'Dereferencing a URL did not result in a JSON object. The ' + 'response was valid JSON, but it was not a JSON object.', 'jsonld.InvalidUrl', {code: 'invalid remote context', url}); } // use empty context if no @context key is present if(!('@context' in context)) { context = {'@context': {}}; } else { context = {'@context': context['@context']}; } // append @context URL to context if given if(remoteDoc.contextUrl) { if(!_isArray(context['@context'])) { context['@context'] = [context['@context']]; } context['@context'].push(remoteDoc.contextUrl); } return {context, remoteDoc}; } }; function _throwInvalidLocalContext(ctx) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context must be an object.', 'jsonld.SyntaxError', { code: 'invalid local context', context: ctx }); } /** * Resolve all relative `@context` URLs in the given context by inline * replacing them with absolute URLs. * * @param context the context. * @param base the base IRI to use to resolve relative IRIs. */ function _resolveContextUrls({context, base}) { if(!context) { return; } const ctx = context['@context']; if(_isString(ctx)) { context['@context'] = prependBase(base, ctx); return; } if(_isArray(ctx)) { for(let i = 0; i < ctx.length; ++i) { const element = ctx[i]; if(_isString(element)) { ctx[i] = prependBase(base, element); continue; } if(_isObject(element)) { _resolveContextUrls({context: {'@context': element}, base}); } } return; } if(!_isObject(ctx)) { // no @context URLs can be found in non-object return; } // ctx is an object, resolve any context URLs in terms for(const term in ctx) { _resolveContextUrls({context: ctx[term], base}); } } /***/ }), /***/ "./node_modules/jsonld/lib/JsonLdError.js": /*!************************************************!*\ !*** ./node_modules/jsonld/lib/JsonLdError.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ module.exports = class JsonLdError extends Error { /** * Creates a JSON-LD Error. * * @param msg the error message. * @param type the error type. * @param details the error details. */ constructor( message = 'An unspecified JSON-LD error occurred.', name = 'jsonld.Error', details = {}) { super(message); this.name = name; this.message = message; this.details = details; } }; /***/ }), /***/ "./node_modules/jsonld/lib/JsonLdProcessor.js": /*!****************************************************!*\ !*** ./node_modules/jsonld/lib/JsonLdProcessor.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ module.exports = jsonld => { class JsonLdProcessor { toString() { return '[object JsonLdProcessor]'; } } Object.defineProperty(JsonLdProcessor, 'prototype', { writable: false, enumerable: false }); Object.defineProperty(JsonLdProcessor.prototype, 'constructor', { writable: true, enumerable: false, configurable: true, value: JsonLdProcessor }); // The Web IDL test harness will check the number of parameters defined in // the functions below. The number of parameters must exactly match the // required (non-optional) parameters of the JsonLdProcessor interface as // defined here: // https://www.w3.org/TR/json-ld-api/#the-jsonldprocessor-interface JsonLdProcessor.compact = function(input, ctx) { if(arguments.length < 2) { return Promise.reject( new TypeError('Could not compact, too few arguments.')); } return jsonld.compact(input, ctx); }; JsonLdProcessor.expand = function(input) { if(arguments.length < 1) { return Promise.reject( new TypeError('Could not expand, too few arguments.')); } return jsonld.expand(input); }; JsonLdProcessor.flatten = function(input) { if(arguments.length < 1) { return Promise.reject( new TypeError('Could not flatten, too few arguments.')); } return jsonld.flatten(input); }; return JsonLdProcessor; }; /***/ }), /***/ "./node_modules/jsonld/lib/NQuads.js": /*!*******************************************!*\ !*** ./node_modules/jsonld/lib/NQuads.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ // TODO: move `NQuads` to its own package module.exports = __webpack_require__(/*! rdf-canonize */ "./node_modules/rdf-canonize/lib/index.js").NQuads; /***/ }), /***/ "./node_modules/jsonld/lib/Rdfa.js": /*!*****************************************!*\ !*** ./node_modules/jsonld/lib/Rdfa.js ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ /* global Node, XMLSerializer */ const { RDF_LANGSTRING, RDF_PLAIN_LITERAL, RDF_OBJECT, RDF_XML_LITERAL, XSD_STRING, } = __webpack_require__(/*! ./constants */ "./node_modules/jsonld/lib/constants.js"); let _Node; if(typeof Node !== 'undefined') { _Node = Node; } else { _Node = { ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12 }; } module.exports = class Rdfa { /** * Parses the RDF dataset found via the data object from the RDFa API. * * @param data the RDFa API data object. * * @return the RDF dataset. */ parse(data) { const dataset = {}; dataset['@default'] = []; const subjects = data.getSubjects(); for(let si = 0; si < subjects.length; ++si) { const subject = subjects[si]; if(subject === null) { continue; } // get all related triples const triples = data.getSubjectTriples(subject); if(triples === null) { continue; } const predicates = triples.predicates; for(const predicate in predicates) { // iterate over objects const objects = predicates[predicate].objects; for(let oi = 0; oi < objects.length; ++oi) { const object = objects[oi]; // create RDF triple const triple = {}; // add subject if(subject.indexOf('_:') === 0) { triple.subject = {type: 'blank node', value: subject}; } else { triple.subject = {type: 'IRI', value: subject}; } // add predicate if(predicate.indexOf('_:') === 0) { triple.predicate = {type: 'blank node', value: predicate}; } else { triple.predicate = {type: 'IRI', value: predicate}; } // serialize XML literal let value = object.value; if(object.type === RDF_XML_LITERAL) { // initialize XMLSerializer const XMLSerializer = getXMLSerializerClass(); const serializer = new XMLSerializer(); value = ''; for(let x = 0; x < object.value.length; x++) { if(object.value[x].nodeType === _Node.ELEMENT_NODE) { value += serializer.serializeToString(object.value[x]); } else if(object.value[x].nodeType === _Node.TEXT_NODE) { value += object.value[x].nodeValue; } } } // add object triple.object = {}; // object is an IRI if(object.type === RDF_OBJECT) { if(object.value.indexOf('_:') === 0) { triple.object.type = 'blank node'; } else { triple.object.type = 'IRI'; } } else { // object is a literal triple.object.type = 'literal'; if(object.type === RDF_PLAIN_LITERAL) { if(object.language) { triple.object.datatype = RDF_LANGSTRING; triple.object.language = object.language; } else { triple.object.datatype = XSD_STRING; } } else { triple.object.datatype = object.type; } } triple.object.value = value; // add triple to dataset in default graph dataset['@default'].push(triple); } } } return dataset; } }; function getXMLSerializerClass() { if(typeof XMLSerializer === 'undefined') { return __webpack_require__(/*! xmldom */ "xmldom").XMLSerializer; } return XMLSerializer; } /***/ }), /***/ "./node_modules/jsonld/lib/RequestQueue.js": /*!*************************************************!*\ !*** ./node_modules/jsonld/lib/RequestQueue.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017-2019 Digital Bazaar, Inc. All rights reserved. */ module.exports = class RequestQueue { /** * Creates a simple queue for requesting documents. */ constructor() { this._requests = {}; } wrapLoader(loader) { const self = this; self._loader = loader; return function(/* url */) { return self.add.apply(self, arguments); }; } async add(url) { let promise = this._requests[url]; if(promise) { // URL already queued, wait for it to load return Promise.resolve(promise); } // queue URL and load it promise = this._requests[url] = this._loader(url); try { return await promise; } finally { delete this._requests[url]; } } }; /***/ }), /***/ "./node_modules/jsonld/lib/ResolvedContext.js": /*!****************************************************!*\ !*** ./node_modules/jsonld/lib/ResolvedContext.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2019 Digital Bazaar, Inc. All rights reserved. */ const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/lru-cache/index.js"); const MAX_ACTIVE_CONTEXTS = 10; module.exports = class ResolvedContext { /** * Creates a ResolvedContext. * * @param document the context document. */ constructor({document}) { this.document = document; // TODO: enable customization of processed context cache // TODO: limit based on size of processed contexts vs. number of them this.cache = new LRU({max: MAX_ACTIVE_CONTEXTS}); } getProcessed(activeCtx) { return this.cache.get(activeCtx); } setProcessed(activeCtx, processedCtx) { this.cache.set(activeCtx, processedCtx); } }; /***/ }), /***/ "./node_modules/jsonld/lib/compact.js": /*!********************************************!*\ !*** ./node_modules/jsonld/lib/compact.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const { isArray: _isArray, isObject: _isObject, isString: _isString, isUndefined: _isUndefined } = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const { isList: _isList, isValue: _isValue, isGraph: _isGraph, isSimpleGraph: _isSimpleGraph, isSubjectReference: _isSubjectReference } = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const { expandIri: _expandIri, getContextValue: _getContextValue, isKeyword: _isKeyword, process: _processContext, processingMode: _processingMode } = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const { removeBase: _removeBase, prependBase: _prependBase } = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const { addValue: _addValue, asArray: _asArray, compareShortestLeast: _compareShortestLeast } = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const api = {}; module.exports = api; /** * Recursively compacts an element using the given active context. All values * must be in expanded form before this method is called. * * @param activeCtx the active context to use. * @param activeProperty the compacted property associated with the element * to compact, null for none. * @param element the element to compact. * @param options the compaction options. * @param compactionMap the compaction map to use. * * @return a promise that resolves to the compacted value. */ api.compact = async ({ activeCtx, activeProperty = null, element, options = {}, compactionMap = () => undefined }) => { // recursively compact array if(_isArray(element)) { let rval = []; for(let i = 0; i < element.length; ++i) { // compact, dropping any null values unless custom mapped let compacted = await api.compact({ activeCtx, activeProperty, element: element[i], options, compactionMap }); if(compacted === null) { compacted = await compactionMap({ unmappedValue: element[i], activeCtx, activeProperty, parent: element, index: i, options }); if(compacted === undefined) { continue; } } rval.push(compacted); } if(options.compactArrays && rval.length === 1) { // use single element if no container is specified const container = _getContextValue( activeCtx, activeProperty, '@container') || []; if(container.length === 0) { rval = rval[0]; } } return rval; } // use any scoped context on activeProperty const ctx = _getContextValue(activeCtx, activeProperty, '@context'); if(!_isUndefined(ctx)) { activeCtx = await _processContext({ activeCtx, localCtx: ctx, propagate: true, overrideProtected: true, options }); } // recursively compact object if(_isObject(element)) { if(options.link && '@id' in element && options.link.hasOwnProperty(element['@id'])) { // check for a linked element to reuse const linked = options.link[element['@id']]; for(let i = 0; i < linked.length; ++i) { if(linked[i].expanded === element) { return linked[i].compacted; } } } // do value compaction on @values and subject references if(_isValue(element) || _isSubjectReference(element)) { const rval = api.compactValue({activeCtx, activeProperty, value: element, options}); if(options.link && _isSubjectReference(element)) { // store linked element if(!(options.link.hasOwnProperty(element['@id']))) { options.link[element['@id']] = []; } options.link[element['@id']].push({expanded: element, compacted: rval}); } return rval; } // if expanded property is @list and we're contained within a list // container, recursively compact this item to an array if(_isList(element)) { const container = _getContextValue( activeCtx, activeProperty, '@container') || []; if(container.includes('@list')) { return api.compact({ activeCtx, activeProperty, element: element['@list'], options, compactionMap }); } } // FIXME: avoid misuse of active property as an expanded property? const insideReverse = (activeProperty === '@reverse'); const rval = {}; // original context before applying property-scoped and local contexts const inputCtx = activeCtx; // revert to previous context, if there is one, // and element is not a value object or a node reference if(!_isValue(element) && !_isSubjectReference(element)) { activeCtx = activeCtx.revertToPreviousContext(); } // apply property-scoped context after reverting term-scoped context const propertyScopedCtx = _getContextValue(inputCtx, activeProperty, '@context'); if(!_isUndefined(propertyScopedCtx)) { activeCtx = await _processContext({ activeCtx, localCtx: propertyScopedCtx, propagate: true, overrideProtected: true, options }); } if(options.link && '@id' in element) { // store linked element if(!options.link.hasOwnProperty(element['@id'])) { options.link[element['@id']] = []; } options.link[element['@id']].push({expanded: element, compacted: rval}); } // apply any context defined on an alias of @type // if key is @type and any compacted value is a term having a local // context, overlay that context let types = element['@type'] || []; if(types.length > 1) { types = Array.from(types).sort(); } // find all type-scoped contexts based on current context, prior to // updating it const typeContext = activeCtx; for(const type of types) { const compactedType = api.compactIri( {activeCtx: typeContext, iri: type, relativeTo: {vocab: true}}); // Use any type-scoped context defined on this value const ctx = _getContextValue(inputCtx, compactedType, '@context'); if(!_isUndefined(ctx)) { activeCtx = await _processContext({ activeCtx, localCtx: ctx, options, propagate: false }); } } // process element keys in order const keys = Object.keys(element).sort(); for(const expandedProperty of keys) { const expandedValue = element[expandedProperty]; // compact @id if(expandedProperty === '@id') { let compactedValue = _asArray(expandedValue).map( expandedIri => api.compactIri({ activeCtx, iri: expandedIri, relativeTo: {vocab: false}, base: options.base })); if(compactedValue.length === 1) { compactedValue = compactedValue[0]; } // use keyword alias and add value const alias = api.compactIri( {activeCtx, iri: '@id', relativeTo: {vocab: true}}); rval[alias] = compactedValue; continue; } // compact @type(s) if(expandedProperty === '@type') { // resolve type values against previous context let compactedValue = _asArray(expandedValue).map( expandedIri => api.compactIri({ activeCtx: inputCtx, iri: expandedIri, relativeTo: {vocab: true} })); if(compactedValue.length === 1) { compactedValue = compactedValue[0]; } // use keyword alias and add value const alias = api.compactIri( {activeCtx, iri: '@type', relativeTo: {vocab: true}}); const container = _getContextValue( activeCtx, alias, '@container') || []; // treat as array for @type if @container includes @set const typeAsSet = container.includes('@set') && _processingMode(activeCtx, 1.1); const isArray = typeAsSet || (_isArray(compactedValue) && expandedValue.length === 0); _addValue(rval, alias, compactedValue, {propertyIsArray: isArray}); continue; } // handle @reverse if(expandedProperty === '@reverse') { // recursively compact expanded value const compactedValue = await api.compact({ activeCtx, activeProperty: '@reverse', element: expandedValue, options, compactionMap }); // handle double-reversed properties for(const compactedProperty in compactedValue) { if(activeCtx.mappings.has(compactedProperty) && activeCtx.mappings.get(compactedProperty).reverse) { const value = compactedValue[compactedProperty]; const container = _getContextValue( activeCtx, compactedProperty, '@container') || []; const useArray = ( container.includes('@set') || !options.compactArrays); _addValue( rval, compactedProperty, value, {propertyIsArray: useArray}); delete compactedValue[compactedProperty]; } } if(Object.keys(compactedValue).length > 0) { // use keyword alias and add value const alias = api.compactIri({ activeCtx, iri: expandedProperty, relativeTo: {vocab: true} }); _addValue(rval, alias, compactedValue); } continue; } if(expandedProperty === '@preserve') { // compact using activeProperty const compactedValue = await api.compact({ activeCtx, activeProperty, element: expandedValue, options, compactionMap }); if(!(_isArray(compactedValue) && compactedValue.length === 0)) { _addValue(rval, expandedProperty, compactedValue); } continue; } // handle @index property if(expandedProperty === '@index') { // drop @index if inside an @index container const container = _getContextValue( activeCtx, activeProperty, '@container') || []; if(container.includes('@index')) { continue; } // use keyword alias and add value const alias = api.compactIri({ activeCtx, iri: expandedProperty, relativeTo: {vocab: true} }); _addValue(rval, alias, expandedValue); continue; } // skip array processing for keywords that aren't // @graph, @list, or @included if(expandedProperty !== '@graph' && expandedProperty !== '@list' && expandedProperty !== '@included' && _isKeyword(expandedProperty)) { // use keyword alias and add value as is const alias = api.compactIri({ activeCtx, iri: expandedProperty, relativeTo: {vocab: true} }); _addValue(rval, alias, expandedValue); continue; } // Note: expanded value must be an array due to expansion algorithm. if(!_isArray(expandedValue)) { throw new JsonLdError( 'JSON-LD expansion error; expanded value must be an array.', 'jsonld.SyntaxError'); } // preserve empty arrays if(expandedValue.length === 0) { const itemActiveProperty = api.compactIri({ activeCtx, iri: expandedProperty, value: expandedValue, relativeTo: {vocab: true}, reverse: insideReverse }); const nestProperty = activeCtx.mappings.has(itemActiveProperty) ? activeCtx.mappings.get(itemActiveProperty)['@nest'] : null; let nestResult = rval; if(nestProperty) { _checkNestProperty(activeCtx, nestProperty, options); if(!_isObject(rval[nestProperty])) { rval[nestProperty] = {}; } nestResult = rval[nestProperty]; } _addValue( nestResult, itemActiveProperty, expandedValue, { propertyIsArray: true }); } // recusively process array values for(const expandedItem of expandedValue) { // compact property and get container type const itemActiveProperty = api.compactIri({ activeCtx, iri: expandedProperty, value: expandedItem, relativeTo: {vocab: true}, reverse: insideReverse }); // if itemActiveProperty is a @nest property, add values to nestResult, // otherwise rval const nestProperty = activeCtx.mappings.has(itemActiveProperty) ? activeCtx.mappings.get(itemActiveProperty)['@nest'] : null; let nestResult = rval; if(nestProperty) { _checkNestProperty(activeCtx, nestProperty, options); if(!_isObject(rval[nestProperty])) { rval[nestProperty] = {}; } nestResult = rval[nestProperty]; } const container = _getContextValue( activeCtx, itemActiveProperty, '@container') || []; // get simple @graph or @list value if appropriate const isGraph = _isGraph(expandedItem); const isList = _isList(expandedItem); let inner; if(isList) { inner = expandedItem['@list']; } else if(isGraph) { inner = expandedItem['@graph']; } // recursively compact expanded item let compactedItem = await api.compact({ activeCtx, activeProperty: itemActiveProperty, element: (isList || isGraph) ? inner : expandedItem, options, compactionMap }); // handle @list if(isList) { // ensure @list value is an array if(!_isArray(compactedItem)) { compactedItem = [compactedItem]; } if(!container.includes('@list')) { // wrap using @list alias compactedItem = { [api.compactIri({ activeCtx, iri: '@list', relativeTo: {vocab: true} })]: compactedItem }; // include @index from expanded @list, if any if('@index' in expandedItem) { compactedItem[api.compactIri({ activeCtx, iri: '@index', relativeTo: {vocab: true} })] = expandedItem['@index']; } } else { _addValue(nestResult, itemActiveProperty, compactedItem, { valueIsArray: true, allowDuplicate: true }); continue; } } // Graph object compaction cases if(isGraph) { if(container.includes('@graph') && (container.includes('@id') || container.includes('@index') && _isSimpleGraph(expandedItem))) { // get or create the map object let mapObject; if(nestResult.hasOwnProperty(itemActiveProperty)) { mapObject = nestResult[itemActiveProperty]; } else { nestResult[itemActiveProperty] = mapObject = {}; } // index on @id or @index or alias of @none const key = (container.includes('@id') ? expandedItem['@id'] : expandedItem['@index']) || api.compactIri({activeCtx, iri: '@none', relativeTo: {vocab: true}}); // add compactedItem to map, using value of `@id` or a new blank // node identifier _addValue( mapObject, key, compactedItem, { propertyIsArray: (!options.compactArrays || container.includes('@set')) }); } else if(container.includes('@graph') && _isSimpleGraph(expandedItem)) { // container includes @graph but not @id or @index and value is a // simple graph object add compact value // if compactedItem contains multiple values, it is wrapped in // `@included` if(_isArray(compactedItem) && compactedItem.length > 1) { compactedItem = {'@included': compactedItem}; } _addValue( nestResult, itemActiveProperty, compactedItem, { propertyIsArray: (!options.compactArrays || container.includes('@set')) }); } else { // wrap using @graph alias, remove array if only one item and // compactArrays not set if(_isArray(compactedItem) && compactedItem.length === 1 && options.compactArrays) { compactedItem = compactedItem[0]; } compactedItem = { [api.compactIri({ activeCtx, iri: '@graph', relativeTo: {vocab: true} })]: compactedItem }; // include @id from expanded graph, if any if('@id' in expandedItem) { compactedItem[api.compactIri({ activeCtx, iri: '@id', relativeTo: {vocab: true} })] = expandedItem['@id']; } // include @index from expanded graph, if any if('@index' in expandedItem) { compactedItem[api.compactIri({ activeCtx, iri: '@index', relativeTo: {vocab: true} })] = expandedItem['@index']; } _addValue( nestResult, itemActiveProperty, compactedItem, { propertyIsArray: (!options.compactArrays || container.includes('@set')) }); } } else if(container.includes('@language') || container.includes('@index') || container.includes('@id') || container.includes('@type')) { // handle language and index maps // get or create the map object let mapObject; if(nestResult.hasOwnProperty(itemActiveProperty)) { mapObject = nestResult[itemActiveProperty]; } else { nestResult[itemActiveProperty] = mapObject = {}; } let key; if(container.includes('@language')) { // if container is a language map, simplify compacted value to // a simple string if(_isValue(compactedItem)) { compactedItem = compactedItem['@value']; } key = expandedItem['@language']; } else if(container.includes('@index')) { const indexKey = _getContextValue( activeCtx, itemActiveProperty, '@index') || '@index'; const containerKey = api.compactIri( {activeCtx, iri: indexKey, relativeTo: {vocab: true}}); if(indexKey === '@index') { key = expandedItem['@index']; delete compactedItem[containerKey]; } else { let others; [key, ...others] = _asArray(compactedItem[indexKey] || []); if(!_isString(key)) { // Will use @none if it isn't a string. key = null; } else { switch(others.length) { case 0: delete compactedItem[indexKey]; break; case 1: compactedItem[indexKey] = others[0]; break; default: compactedItem[indexKey] = others; break; } } } } else if(container.includes('@id')) { const idKey = api.compactIri({activeCtx, iri: '@id', relativeTo: {vocab: true}}); key = compactedItem[idKey]; delete compactedItem[idKey]; } else if(container.includes('@type')) { const typeKey = api.compactIri({ activeCtx, iri: '@type', relativeTo: {vocab: true} }); let types; [key, ...types] = _asArray(compactedItem[typeKey] || []); switch(types.length) { case 0: delete compactedItem[typeKey]; break; case 1: compactedItem[typeKey] = types[0]; break; default: compactedItem[typeKey] = types; break; } // If compactedItem contains a single entry // whose key maps to @id, recompact without @type if(Object.keys(compactedItem).length === 1 && '@id' in expandedItem) { compactedItem = await api.compact({ activeCtx, activeProperty: itemActiveProperty, element: {'@id': expandedItem['@id']}, options, compactionMap }); } } // if compacting this value which has no key, index on @none if(!key) { key = api.compactIri({activeCtx, iri: '@none', relativeTo: {vocab: true}}); } // add compact value to map object using key from expanded value // based on the container type _addValue( mapObject, key, compactedItem, { propertyIsArray: container.includes('@set') }); } else { // use an array if: compactArrays flag is false, // @container is @set or @list , value is an empty // array, or key is @graph const isArray = (!options.compactArrays || container.includes('@set') || container.includes('@list') || (_isArray(compactedItem) && compactedItem.length === 0) || expandedProperty === '@list' || expandedProperty === '@graph'); // add compact value _addValue( nestResult, itemActiveProperty, compactedItem, {propertyIsArray: isArray}); } } } return rval; } // only primitives remain which are already compact return element; }; /** * Compacts an IRI or keyword into a term or prefix if it can be. If the * IRI has an associated value it may be passed. * * @param activeCtx the active context to use. * @param iri the IRI to compact. * @param value the value to check or null. * @param relativeTo options for how to compact IRIs: * vocab: true to split after @vocab, false not to. * @param reverse true if a reverse property is being compacted, false if not. * @param base the absolute URL to use for compacting document-relative IRIs. * * @return the compacted term, prefix, keyword alias, or the original IRI. */ api.compactIri = ({ activeCtx, iri, value = null, relativeTo = {vocab: false}, reverse = false, base = null }) => { // can't compact null if(iri === null) { return iri; } // if context is from a property term scoped context composed with a // type-scoped context, then use the previous context instead if(activeCtx.isPropertyTermScoped && activeCtx.previousContext) { activeCtx = activeCtx.previousContext; } const inverseCtx = activeCtx.getInverse(); // if term is a keyword, it may be compacted to a simple alias if(_isKeyword(iri) && iri in inverseCtx && '@none' in inverseCtx[iri] && '@type' in inverseCtx[iri]['@none'] && '@none' in inverseCtx[iri]['@none']['@type']) { return inverseCtx[iri]['@none']['@type']['@none']; } // use inverse context to pick a term if iri is relative to vocab if(relativeTo.vocab && iri in inverseCtx) { const defaultLanguage = activeCtx['@language'] || '@none'; // prefer @index if available in value const containers = []; if(_isObject(value) && '@index' in value && !('@graph' in value)) { containers.push('@index', '@index@set'); } // if value is a preserve object, use its value if(_isObject(value) && '@preserve' in value) { value = value['@preserve'][0]; } // prefer most specific container including @graph, prefering @set // variations if(_isGraph(value)) { // favor indexmap if the graph is indexed if('@index' in value) { containers.push( '@graph@index', '@graph@index@set', '@index', '@index@set'); } // favor idmap if the graph is has an @id if('@id' in value) { containers.push( '@graph@id', '@graph@id@set'); } containers.push('@graph', '@graph@set', '@set'); // allow indexmap if the graph is not indexed if(!('@index' in value)) { containers.push( '@graph@index', '@graph@index@set', '@index', '@index@set'); } // allow idmap if the graph does not have an @id if(!('@id' in value)) { containers.push('@graph@id', '@graph@id@set'); } } else if(_isObject(value) && !_isValue(value)) { containers.push('@id', '@id@set', '@type', '@set@type'); } // defaults for term selection based on type/language let typeOrLanguage = '@language'; let typeOrLanguageValue = '@null'; if(reverse) { typeOrLanguage = '@type'; typeOrLanguageValue = '@reverse'; containers.push('@set'); } else if(_isList(value)) { // choose the most specific term that works for all elements in @list // only select @list containers if @index is NOT in value if(!('@index' in value)) { containers.push('@list'); } const list = value['@list']; if(list.length === 0) { // any empty list can be matched against any term that uses the // @list container regardless of @type or @language typeOrLanguage = '@any'; typeOrLanguageValue = '@none'; } else { let commonLanguage = (list.length === 0) ? defaultLanguage : null; let commonType = null; for(let i = 0; i < list.length; ++i) { const item = list[i]; let itemLanguage = '@none'; let itemType = '@none'; if(_isValue(item)) { if('@direction' in item) { const lang = (item['@language'] || '').toLowerCase(); const dir = item['@direction']; itemLanguage = `${lang}_${dir}`; } else if('@language' in item) { itemLanguage = item['@language'].toLowerCase(); } else if('@type' in item) { itemType = item['@type']; } else { // plain literal itemLanguage = '@null'; } } else { itemType = '@id'; } if(commonLanguage === null) { commonLanguage = itemLanguage; } else if(itemLanguage !== commonLanguage && _isValue(item)) { commonLanguage = '@none'; } if(commonType === null) { commonType = itemType; } else if(itemType !== commonType) { commonType = '@none'; } // there are different languages and types in the list, so choose // the most generic term, no need to keep iterating the list if(commonLanguage === '@none' && commonType === '@none') { break; } } commonLanguage = commonLanguage || '@none'; commonType = commonType || '@none'; if(commonType !== '@none') { typeOrLanguage = '@type'; typeOrLanguageValue = commonType; } else { typeOrLanguageValue = commonLanguage; } } } else { if(_isValue(value)) { if('@language' in value && !('@index' in value)) { containers.push('@language', '@language@set'); typeOrLanguageValue = value['@language']; const dir = value['@direction']; if(dir) { typeOrLanguageValue = `${typeOrLanguageValue}_${dir}`; } } else if('@direction' in value && !('@index' in value)) { typeOrLanguageValue = `_${value['@direction']}`; } else if('@type' in value) { typeOrLanguage = '@type'; typeOrLanguageValue = value['@type']; } } else { typeOrLanguage = '@type'; typeOrLanguageValue = '@id'; } containers.push('@set'); } // do term selection containers.push('@none'); // an index map can be used to index values using @none, so add as a low // priority if(_isObject(value) && !('@index' in value)) { // allow indexing even if no @index present containers.push('@index', '@index@set'); } // values without type or language can use @language map if(_isValue(value) && Object.keys(value).length === 1) { // allow indexing even if no @index present containers.push('@language', '@language@set'); } const term = _selectTerm( activeCtx, iri, value, containers, typeOrLanguage, typeOrLanguageValue); if(term !== null) { return term; } } // no term match, use @vocab if available if(relativeTo.vocab) { if('@vocab' in activeCtx) { // determine if vocab is a prefix of the iri const vocab = activeCtx['@vocab']; if(iri.indexOf(vocab) === 0 && iri !== vocab) { // use suffix as relative iri if it is not a term in the active context const suffix = iri.substr(vocab.length); if(!activeCtx.mappings.has(suffix)) { return suffix; } } } } // no term or @vocab match, check for possible CURIEs let choice = null; // TODO: make FastCurieMap a class with a method to do this lookup const partialMatches = []; let iriMap = activeCtx.fastCurieMap; // check for partial matches of against `iri`, which means look until // iri.length - 1, not full length const maxPartialLength = iri.length - 1; for(let i = 0; i < maxPartialLength && iri[i] in iriMap; ++i) { iriMap = iriMap[iri[i]]; if('' in iriMap) { partialMatches.push(iriMap[''][0]); } } // check partial matches in reverse order to prefer longest ones first for(let i = partialMatches.length - 1; i >= 0; --i) { const entry = partialMatches[i]; const terms = entry.terms; for(const term of terms) { // a CURIE is usable if: // 1. it has no mapping, OR // 2. value is null, which means we're not compacting an @value, AND // the mapping matches the IRI const curie = term + ':' + iri.substr(entry.iri.length); const isUsableCurie = (activeCtx.mappings.get(term)._prefix && (!activeCtx.mappings.has(curie) || (value === null && activeCtx.mappings.get(curie)['@id'] === iri))); // select curie if it is shorter or the same length but lexicographically // less than the current choice if(isUsableCurie && (choice === null || _compareShortestLeast(curie, choice) < 0)) { choice = curie; } } } // return chosen curie if(choice !== null) { return choice; } // If iri could be confused with a compact IRI using a term in this context, // signal an error for(const [term, td] of activeCtx.mappings) { if(td && td._prefix && iri.startsWith(term + ':')) { throw new JsonLdError( `Absolute IRI "${iri}" confused with prefix "${term}".`, 'jsonld.SyntaxError', {code: 'IRI confused with prefix', context: activeCtx}); } } // compact IRI relative to base if(!relativeTo.vocab) { if('@base' in activeCtx) { if(!activeCtx['@base']) { // The None case preserves rval as potentially relative return iri; } else { return _removeBase(_prependBase(base, activeCtx['@base']), iri); } } else { return _removeBase(base, iri); } } // return IRI as is return iri; }; /** * Performs value compaction on an object with '@value' or '@id' as the only * property. * * @param activeCtx the active context. * @param activeProperty the active property that points to the value. * @param value the value to compact. * @param {Object} [options] - processing options. * * @return the compaction result. */ api.compactValue = ({activeCtx, activeProperty, value, options}) => { // value is a @value if(_isValue(value)) { // get context rules const type = _getContextValue(activeCtx, activeProperty, '@type'); const language = _getContextValue(activeCtx, activeProperty, '@language'); const direction = _getContextValue(activeCtx, activeProperty, '@direction'); const container = _getContextValue(activeCtx, activeProperty, '@container') || []; // whether or not the value has an @index that must be preserved const preserveIndex = '@index' in value && !container.includes('@index'); // if there's no @index to preserve ... if(!preserveIndex && type !== '@none') { // matching @type or @language specified in context, compact value if(value['@type'] === type) { return value['@value']; } if('@language' in value && value['@language'] === language && '@direction' in value && value['@direction'] === direction) { return value['@value']; } if('@language' in value && value['@language'] === language) { return value['@value']; } if('@direction' in value && value['@direction'] === direction) { return value['@value']; } } // return just the value of @value if all are true: // 1. @value is the only key or @index isn't being preserved // 2. there is no default language or @value is not a string or // the key has a mapping with a null @language const keyCount = Object.keys(value).length; const isValueOnlyKey = (keyCount === 1 || (keyCount === 2 && '@index' in value && !preserveIndex)); const hasDefaultLanguage = ('@language' in activeCtx); const isValueString = _isString(value['@value']); const hasNullMapping = (activeCtx.mappings.has(activeProperty) && activeCtx.mappings.get(activeProperty)['@language'] === null); if(isValueOnlyKey && type !== '@none' && (!hasDefaultLanguage || !isValueString || hasNullMapping)) { return value['@value']; } const rval = {}; // preserve @index if(preserveIndex) { rval[api.compactIri({ activeCtx, iri: '@index', relativeTo: {vocab: true} })] = value['@index']; } if('@type' in value) { // compact @type IRI rval[api.compactIri({ activeCtx, iri: '@type', relativeTo: {vocab: true} })] = api.compactIri( {activeCtx, iri: value['@type'], relativeTo: {vocab: true}}); } else if('@language' in value) { // alias @language rval[api.compactIri({ activeCtx, iri: '@language', relativeTo: {vocab: true} })] = value['@language']; } if('@direction' in value) { // alias @direction rval[api.compactIri({ activeCtx, iri: '@direction', relativeTo: {vocab: true} })] = value['@direction']; } // alias @value rval[api.compactIri({ activeCtx, iri: '@value', relativeTo: {vocab: true} })] = value['@value']; return rval; } // value is a subject reference const expandedProperty = _expandIri(activeCtx, activeProperty, {vocab: true}, options); const type = _getContextValue(activeCtx, activeProperty, '@type'); const compacted = api.compactIri({ activeCtx, iri: value['@id'], relativeTo: {vocab: type === '@vocab'}, base: options.base}); // compact to scalar if(type === '@id' || type === '@vocab' || expandedProperty === '@graph') { return compacted; } return { [api.compactIri({ activeCtx, iri: '@id', relativeTo: {vocab: true} })]: compacted }; }; /** * Picks the preferred compaction term from the given inverse context entry. * * @param activeCtx the active context. * @param iri the IRI to pick the term for. * @param value the value to pick the term for. * @param containers the preferred containers. * @param typeOrLanguage either '@type' or '@language'. * @param typeOrLanguageValue the preferred value for '@type' or '@language'. * * @return the preferred term. */ function _selectTerm( activeCtx, iri, value, containers, typeOrLanguage, typeOrLanguageValue) { if(typeOrLanguageValue === null) { typeOrLanguageValue = '@null'; } // preferences for the value of @type or @language const prefs = []; // determine prefs for @id based on whether or not value compacts to a term if((typeOrLanguageValue === '@id' || typeOrLanguageValue === '@reverse') && _isObject(value) && '@id' in value) { // prefer @reverse first if(typeOrLanguageValue === '@reverse') { prefs.push('@reverse'); } // try to compact value to a term const term = api.compactIri( {activeCtx, iri: value['@id'], relativeTo: {vocab: true}}); if(activeCtx.mappings.has(term) && activeCtx.mappings.get(term) && activeCtx.mappings.get(term)['@id'] === value['@id']) { // prefer @vocab prefs.push.apply(prefs, ['@vocab', '@id']); } else { // prefer @id prefs.push.apply(prefs, ['@id', '@vocab']); } } else { prefs.push(typeOrLanguageValue); // consider direction only const langDir = prefs.find(el => el.includes('_')); if(langDir) { // consider _dir portion prefs.push(langDir.replace(/^[^_]+_/, '_')); } } prefs.push('@none'); const containerMap = activeCtx.inverse[iri]; for(const container of containers) { // if container not available in the map, continue if(!(container in containerMap)) { continue; } const typeOrLanguageValueMap = containerMap[container][typeOrLanguage]; for(const pref of prefs) { // if type/language option not available in the map, continue if(!(pref in typeOrLanguageValueMap)) { continue; } // select term return typeOrLanguageValueMap[pref]; } } return null; } /** * The value of `@nest` in the term definition must either be `@nest`, or a term * which resolves to `@nest`. * * @param activeCtx the active context. * @param nestProperty a term in the active context or `@nest`. * @param {Object} [options] - processing options. */ function _checkNestProperty(activeCtx, nestProperty, options) { if(_expandIri(activeCtx, nestProperty, {vocab: true}, options) !== '@nest') { throw new JsonLdError( 'JSON-LD compact error; nested property must have an @nest value ' + 'resolving to @nest.', 'jsonld.SyntaxError', {code: 'invalid @nest value'}); } } /***/ }), /***/ "./node_modules/jsonld/lib/constants.js": /*!**********************************************!*\ !*** ./node_modules/jsonld/lib/constants.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; const XSD = 'http://www.w3.org/2001/XMLSchema#'; module.exports = { // TODO: Deprecated and will be removed later. Use LINK_HEADER_CONTEXT. LINK_HEADER_REL: 'http://www.w3.org/ns/json-ld#context', LINK_HEADER_CONTEXT: 'http://www.w3.org/ns/json-ld#context', RDF, RDF_LIST: RDF + 'List', RDF_FIRST: RDF + 'first', RDF_REST: RDF + 'rest', RDF_NIL: RDF + 'nil', RDF_TYPE: RDF + 'type', RDF_PLAIN_LITERAL: RDF + 'PlainLiteral', RDF_XML_LITERAL: RDF + 'XMLLiteral', RDF_JSON_LITERAL: RDF + 'JSON', RDF_OBJECT: RDF + 'object', RDF_LANGSTRING: RDF + 'langString', XSD, XSD_BOOLEAN: XSD + 'boolean', XSD_DOUBLE: XSD + 'double', XSD_INTEGER: XSD + 'integer', XSD_STRING: XSD + 'string', }; /***/ }), /***/ "./node_modules/jsonld/lib/context.js": /*!********************************************!*\ !*** ./node_modules/jsonld/lib/context.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017-2019 Digital Bazaar, Inc. All rights reserved. */ const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const { isArray: _isArray, isObject: _isObject, isString: _isString, isUndefined: _isUndefined } = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const { isAbsolute: _isAbsoluteIri, isRelative: _isRelativeIri, prependBase } = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const { asArray: _asArray, compareShortestLeast: _compareShortestLeast } = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const INITIAL_CONTEXT_CACHE = new Map(); const INITIAL_CONTEXT_CACHE_MAX_SIZE = 10000; const KEYWORD_PATTERN = /^@[a-zA-Z]+$/; const api = {}; module.exports = api; /** * Processes a local context and returns a new active context. * * @param activeCtx the current active context. * @param localCtx the local context to process. * @param options the context processing options. * @param propagate `true` if `false`, retains any previously defined term, * which can be rolled back when the descending into a new node object. * @param overrideProtected `false` allows protected terms to be modified. * * @return a Promise that resolves to the new active context. */ api.process = async ({ activeCtx, localCtx, options, propagate = true, overrideProtected = false, cycles = new Set() }) => { // normalize local context to an array of @context objects if(_isObject(localCtx) && '@context' in localCtx && _isArray(localCtx['@context'])) { localCtx = localCtx['@context']; } const ctxs = _asArray(localCtx); // no contexts in array, return current active context w/o changes if(ctxs.length === 0) { return activeCtx; } // resolve contexts const resolved = await options.contextResolver.resolve({ activeCtx, context: localCtx, documentLoader: options.documentLoader, base: options.base }); // override propagate if first resolved context has `@propagate` if(_isObject(resolved[0].document) && typeof resolved[0].document['@propagate'] === 'boolean') { // retrieve early, error checking done later propagate = resolved[0].document['@propagate']; } // process each context in order, update active context // on each iteration to ensure proper caching let rval = activeCtx; // track the previous context // if not propagating, make sure rval has a previous context if(!propagate && !rval.previousContext) { // clone `rval` context before updating rval = rval.clone(); rval.previousContext = activeCtx; } for(const resolvedContext of resolved) { let {document: ctx} = resolvedContext; // update active context to one computed from last iteration activeCtx = rval; // reset to initial context if(ctx === null) { // We can't nullify if there are protected terms and we're // not allowing overrides (e.g. processing a property term scoped context) if(!overrideProtected && Object.keys(activeCtx.protected).length !== 0) { const protectedMode = (options && options.protectedMode) || 'error'; if(protectedMode === 'error') { throw new JsonLdError( 'Tried to nullify a context with protected terms outside of ' + 'a term definition.', 'jsonld.SyntaxError', {code: 'invalid context nullification'}); } else if(protectedMode === 'warn') { // FIXME: remove logging and use a handler console.warn('WARNING: invalid context nullification'); // get processed context from cache if available const processed = resolvedContext.getProcessed(activeCtx); if(processed) { rval = activeCtx = processed; continue; } const oldActiveCtx = activeCtx; // copy all protected term definitions to fresh initial context rval = activeCtx = api.getInitialContext(options).clone(); for(const [term, _protected] of Object.entries(oldActiveCtx.protected)) { if(_protected) { activeCtx.mappings[term] = util.clone(oldActiveCtx.mappings[term]); } } activeCtx.protected = util.clone(oldActiveCtx.protected); // cache processed result resolvedContext.setProcessed(oldActiveCtx, rval); continue; } throw new JsonLdError( 'Invalid protectedMode.', 'jsonld.SyntaxError', {code: 'invalid protected mode', context: localCtx, protectedMode}); } rval = activeCtx = api.getInitialContext(options).clone(); continue; } // get processed context from cache if available const processed = resolvedContext.getProcessed(activeCtx); if(processed) { rval = activeCtx = processed; continue; } // dereference @context key if present if(_isObject(ctx) && '@context' in ctx) { ctx = ctx['@context']; } // context must be an object by now, all URLs retrieved before this call if(!_isObject(ctx)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context must be an object.', 'jsonld.SyntaxError', {code: 'invalid local context', context: ctx}); } // TODO: there is likely a `previousContext` cloning optimization that // could be applied here (no need to copy it under certain conditions) // clone context before updating it rval = rval.clone(); // define context mappings for keys in local context const defined = new Map(); // handle @version if('@version' in ctx) { if(ctx['@version'] !== 1.1) { throw new JsonLdError( 'Unsupported JSON-LD version: ' + ctx['@version'], 'jsonld.UnsupportedVersion', {code: 'invalid @version value', context: ctx}); } if(activeCtx.processingMode && activeCtx.processingMode === 'json-ld-1.0') { throw new JsonLdError( '@version: ' + ctx['@version'] + ' not compatible with ' + activeCtx.processingMode, 'jsonld.ProcessingModeConflict', {code: 'processing mode conflict', context: ctx}); } rval.processingMode = 'json-ld-1.1'; rval['@version'] = ctx['@version']; defined.set('@version', true); } // if not set explicitly, set processingMode to "json-ld-1.1" rval.processingMode = rval.processingMode || activeCtx.processingMode; // handle @base if('@base' in ctx) { let base = ctx['@base']; if(base === null || _isAbsoluteIri(base)) { // no action } else if(_isRelativeIri(base)) { base = prependBase(rval['@base'], base); } else { throw new JsonLdError( 'Invalid JSON-LD syntax; the value of "@base" in a ' + '@context must be an absolute IRI, a relative IRI, or null.', 'jsonld.SyntaxError', {code: 'invalid base IRI', context: ctx}); } rval['@base'] = base; defined.set('@base', true); } // handle @vocab if('@vocab' in ctx) { const value = ctx['@vocab']; if(value === null) { delete rval['@vocab']; } else if(!_isString(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; the value of "@vocab" in a ' + '@context must be a string or null.', 'jsonld.SyntaxError', {code: 'invalid vocab mapping', context: ctx}); } else if(!_isAbsoluteIri(value) && api.processingMode(rval, 1.0)) { throw new JsonLdError( 'Invalid JSON-LD syntax; the value of "@vocab" in a ' + '@context must be an absolute IRI.', 'jsonld.SyntaxError', {code: 'invalid vocab mapping', context: ctx}); } else { rval['@vocab'] = _expandIri(rval, value, {vocab: true, base: true}, undefined, undefined, options); } defined.set('@vocab', true); } // handle @language if('@language' in ctx) { const value = ctx['@language']; if(value === null) { delete rval['@language']; } else if(!_isString(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; the value of "@language" in a ' + '@context must be a string or null.', 'jsonld.SyntaxError', {code: 'invalid default language', context: ctx}); } else { rval['@language'] = value.toLowerCase(); } defined.set('@language', true); } // handle @direction if('@direction' in ctx) { const value = ctx['@direction']; if(activeCtx.processingMode === 'json-ld-1.0') { throw new JsonLdError( 'Invalid JSON-LD syntax; @direction not compatible with ' + activeCtx.processingMode, 'jsonld.SyntaxError', {code: 'invalid context member', context: ctx}); } if(value === null) { delete rval['@direction']; } else if(value !== 'ltr' && value !== 'rtl') { throw new JsonLdError( 'Invalid JSON-LD syntax; the value of "@direction" in a ' + '@context must be null, "ltr", or "rtl".', 'jsonld.SyntaxError', {code: 'invalid base direction', context: ctx}); } else { rval['@direction'] = value; } defined.set('@direction', true); } // handle @propagate // note: we've already extracted it, here we just do error checking if('@propagate' in ctx) { const value = ctx['@propagate']; if(activeCtx.processingMode === 'json-ld-1.0') { throw new JsonLdError( 'Invalid JSON-LD syntax; @propagate not compatible with ' + activeCtx.processingMode, 'jsonld.SyntaxError', {code: 'invalid context entry', context: ctx}); } if(typeof value !== 'boolean') { throw new JsonLdError( 'Invalid JSON-LD syntax; @propagate value must be a boolean.', 'jsonld.SyntaxError', {code: 'invalid @propagate value', context: localCtx}); } defined.set('@propagate', true); } // handle @import if('@import' in ctx) { const value = ctx['@import']; if(activeCtx.processingMode === 'json-ld-1.0') { throw new JsonLdError( 'Invalid JSON-LD syntax; @import not compatible with ' + activeCtx.processingMode, 'jsonld.SyntaxError', {code: 'invalid context entry', context: ctx}); } if(!_isString(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @import must be a string.', 'jsonld.SyntaxError', {code: 'invalid @import value', context: localCtx}); } // resolve contexts const resolvedImport = await options.contextResolver.resolve({ activeCtx, context: value, documentLoader: options.documentLoader, base: options.base }); if(resolvedImport.length !== 1) { throw new JsonLdError( 'Invalid JSON-LD syntax; @import must reference a single context.', 'jsonld.SyntaxError', {code: 'invalid remote context', context: localCtx}); } const processedImport = resolvedImport[0].getProcessed(activeCtx); if(processedImport) { // Note: if the same context were used in this active context // as a reference context, then processed_input might not // be a dict. ctx = processedImport; } else { const importCtx = resolvedImport[0].document; if('@import' in importCtx) { throw new JsonLdError( 'Invalid JSON-LD syntax: ' + 'imported context must not include @import.', 'jsonld.SyntaxError', {code: 'invalid context entry', context: localCtx}); } // merge ctx into importCtx and replace rval with the result for(const key in importCtx) { if(!ctx.hasOwnProperty(key)) { ctx[key] = importCtx[key]; } } // Note: this could potenially conflict if the import // were used in the same active context as a referenced // context and an import. In this case, we // could override the cached result, but seems unlikely. resolvedImport[0].setProcessed(activeCtx, ctx); } defined.set('@import', true); } // handle @protected; determine whether this sub-context is declaring // all its terms to be "protected" (exceptions can be made on a // per-definition basis) defined.set('@protected', ctx['@protected'] || false); // process all other keys for(const key in ctx) { api.createTermDefinition({ activeCtx: rval, localCtx: ctx, term: key, defined, options, overrideProtected }); if(_isObject(ctx[key]) && '@context' in ctx[key]) { const keyCtx = ctx[key]['@context']; let process = true; if(_isString(keyCtx)) { const url = prependBase(options.base, keyCtx); // track processed contexts to avoid scoped context recursion if(cycles.has(url)) { process = false; } else { cycles.add(url); } } // parse context to validate if(process) { try { await api.process({ activeCtx: rval.clone(), localCtx: ctx[key]['@context'], overrideProtected: true, options, cycles }); } catch(e) { throw new JsonLdError( 'Invalid JSON-LD syntax; invalid scoped context.', 'jsonld.SyntaxError', { code: 'invalid scoped context', context: ctx[key]['@context'], term: key }); } } } } // cache processed result resolvedContext.setProcessed(activeCtx, rval); } return rval; }; /** * Creates a term definition during context processing. * * @param activeCtx the current active context. * @param localCtx the local context being processed. * @param term the term in the local context to define the mapping for. * @param defined a map of defining/defined keys to detect cycles and prevent * double definitions. * @param {Object} [options] - creation options. * @param {string} [options.protectedMode="error"] - "error" to throw error * on `@protected` constraint violation, "warn" to allow violations and * signal a warning. * @param overrideProtected `false` allows protected terms to be modified. */ api.createTermDefinition = ({ activeCtx, localCtx, term, defined, options, overrideProtected = false, }) => { if(defined.has(term)) { // term already defined if(defined.get(term)) { return; } // cycle detected throw new JsonLdError( 'Cyclical context definition detected.', 'jsonld.CyclicalContext', {code: 'cyclic IRI mapping', context: localCtx, term}); } // now defining term defined.set(term, false); // get context term value let value; if(localCtx.hasOwnProperty(term)) { value = localCtx[term]; } if(term === '@type' && _isObject(value) && (value['@container'] || '@set') === '@set' && api.processingMode(activeCtx, 1.1)) { const validKeys = ['@container', '@id', '@protected']; const keys = Object.keys(value); if(keys.length === 0 || keys.some(k => !validKeys.includes(k))) { throw new JsonLdError( 'Invalid JSON-LD syntax; keywords cannot be overridden.', 'jsonld.SyntaxError', {code: 'keyword redefinition', context: localCtx, term}); } } else if(api.isKeyword(term)) { throw new JsonLdError( 'Invalid JSON-LD syntax; keywords cannot be overridden.', 'jsonld.SyntaxError', {code: 'keyword redefinition', context: localCtx, term}); } else if(term.match(KEYWORD_PATTERN)) { // FIXME: remove logging and use a handler console.warn('WARNING: terms beginning with "@" are reserved' + ' for future use and ignored', {term}); return; } else if(term === '') { throw new JsonLdError( 'Invalid JSON-LD syntax; a term cannot be an empty string.', 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } // keep reference to previous mapping for potential `@protected` check const previousMapping = activeCtx.mappings.get(term); // remove old mapping if(activeCtx.mappings.has(term)) { activeCtx.mappings.delete(term); } // convert short-hand value to object w/@id let simpleTerm = false; if(_isString(value) || value === null) { simpleTerm = true; value = {'@id': value}; } if(!_isObject(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context term values must be ' + 'strings or objects.', 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } // create new mapping const mapping = {}; activeCtx.mappings.set(term, mapping); mapping.reverse = false; // make sure term definition only has expected keywords const validKeys = ['@container', '@id', '@language', '@reverse', '@type']; // JSON-LD 1.1 support if(api.processingMode(activeCtx, 1.1)) { validKeys.push( '@context', '@direction', '@index', '@nest', '@prefix', '@protected'); } for(const kw in value) { if(!validKeys.includes(kw)) { throw new JsonLdError( 'Invalid JSON-LD syntax; a term definition must not contain ' + kw, 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } } // always compute whether term has a colon as an optimization for // _compactIri const colon = term.indexOf(':'); mapping._termHasColon = (colon > 0); if('@reverse' in value) { if('@id' in value) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @reverse term definition must not ' + 'contain @id.', 'jsonld.SyntaxError', {code: 'invalid reverse property', context: localCtx}); } if('@nest' in value) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @reverse term definition must not ' + 'contain @nest.', 'jsonld.SyntaxError', {code: 'invalid reverse property', context: localCtx}); } const reverse = value['@reverse']; if(!_isString(reverse)) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @context @reverse value must be a string.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx}); } if(!api.isKeyword(reverse) && reverse.match(KEYWORD_PATTERN)) { // FIXME: remove logging and use a handler console.warn('WARNING: values beginning with "@" are reserved' + ' for future use and ignored', {reverse}); if(previousMapping) { activeCtx.mappings.set(term, previousMapping); } else { activeCtx.mappings.delete(term); } return; } // expand and add @id mapping const id = _expandIri( activeCtx, reverse, {vocab: true, base: false}, localCtx, defined, options); if(!_isAbsoluteIri(id)) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @context @reverse value must be an ' + 'absolute IRI or a blank node identifier.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx}); } mapping['@id'] = id; mapping.reverse = true; } else if('@id' in value) { let id = value['@id']; if(id && !_isString(id)) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @context @id value must be an array ' + 'of strings or a string.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx}); } if(id === null) { // reserve a null term, which may be protected mapping['@id'] = null; } else if(!api.isKeyword(id) && id.match(KEYWORD_PATTERN)) { // FIXME: remove logging and use a handler console.warn('WARNING: values beginning with "@" are reserved' + ' for future use and ignored', {id}); if(previousMapping) { activeCtx.mappings.set(term, previousMapping); } else { activeCtx.mappings.delete(term); } return; } else if(id !== term) { // expand and add @id mapping id = _expandIri( activeCtx, id, {vocab: true, base: false}, localCtx, defined, options); if(!_isAbsoluteIri(id) && !api.isKeyword(id)) { throw new JsonLdError( 'Invalid JSON-LD syntax; a @context @id value must be an ' + 'absolute IRI, a blank node identifier, or a keyword.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx}); } // if term has the form of an IRI it must map the same if(term.match(/(?::[^:])|\//)) { const termDefined = new Map(defined).set(term, true); const termIri = _expandIri( activeCtx, term, {vocab: true, base: false}, localCtx, termDefined, options); if(termIri !== id) { throw new JsonLdError( 'Invalid JSON-LD syntax; term in form of IRI must ' + 'expand to definition.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx}); } } mapping['@id'] = id; // indicate if this term may be used as a compact IRI prefix mapping._prefix = (simpleTerm && !mapping._termHasColon && id.match(/[:\/\?#\[\]@]$/)); } } if(!('@id' in mapping)) { // see if the term has a prefix if(mapping._termHasColon) { const prefix = term.substr(0, colon); if(localCtx.hasOwnProperty(prefix)) { // define parent prefix api.createTermDefinition({ activeCtx, localCtx, term: prefix, defined, options }); } if(activeCtx.mappings.has(prefix)) { // set @id based on prefix parent const suffix = term.substr(colon + 1); mapping['@id'] = activeCtx.mappings.get(prefix)['@id'] + suffix; } else { // term is an absolute IRI mapping['@id'] = term; } } else if(term === '@type') { // Special case, were we've previously determined that container is @set mapping['@id'] = term; } else { // non-IRIs *must* define @ids if @vocab is not available if(!('@vocab' in activeCtx)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context terms must define an @id.', 'jsonld.SyntaxError', {code: 'invalid IRI mapping', context: localCtx, term}); } // prepend vocab to term mapping['@id'] = activeCtx['@vocab'] + term; } } // Handle term protection if(value['@protected'] === true || (defined.get('@protected') === true && value['@protected'] !== false)) { activeCtx.protected[term] = true; mapping.protected = true; } // IRI mapping now defined defined.set(term, true); if('@type' in value) { let type = value['@type']; if(!_isString(type)) { throw new JsonLdError( 'Invalid JSON-LD syntax; an @context @type value must be a string.', 'jsonld.SyntaxError', {code: 'invalid type mapping', context: localCtx}); } if((type === '@json' || type === '@none')) { if(api.processingMode(activeCtx, 1.0)) { throw new JsonLdError( 'Invalid JSON-LD syntax; an @context @type value must not be ' + `"${type}" in JSON-LD 1.0 mode.`, 'jsonld.SyntaxError', {code: 'invalid type mapping', context: localCtx}); } } else if(type !== '@id' && type !== '@vocab') { // expand @type to full IRI type = _expandIri( activeCtx, type, {vocab: true, base: false}, localCtx, defined, options); if(!_isAbsoluteIri(type)) { throw new JsonLdError( 'Invalid JSON-LD syntax; an @context @type value must be an ' + 'absolute IRI.', 'jsonld.SyntaxError', {code: 'invalid type mapping', context: localCtx}); } if(type.indexOf('_:') === 0) { throw new JsonLdError( 'Invalid JSON-LD syntax; an @context @type value must be an IRI, ' + 'not a blank node identifier.', 'jsonld.SyntaxError', {code: 'invalid type mapping', context: localCtx}); } } // add @type to mapping mapping['@type'] = type; } if('@container' in value) { // normalize container to an array form const container = _isString(value['@container']) ? [value['@container']] : (value['@container'] || []); const validContainers = ['@list', '@set', '@index', '@language']; let isValid = true; const hasSet = container.includes('@set'); // JSON-LD 1.1 support if(api.processingMode(activeCtx, 1.1)) { validContainers.push('@graph', '@id', '@type'); // check container length if(container.includes('@list')) { if(container.length !== 1) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @container with @list must ' + 'have no other values', 'jsonld.SyntaxError', {code: 'invalid container mapping', context: localCtx}); } } else if(container.includes('@graph')) { if(container.some(key => key !== '@graph' && key !== '@id' && key !== '@index' && key !== '@set')) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @container with @graph must ' + 'have no other values other than @id, @index, and @set', 'jsonld.SyntaxError', {code: 'invalid container mapping', context: localCtx}); } } else { // otherwise, container may also include @set isValid &= container.length <= (hasSet ? 2 : 1); } if(container.includes('@type')) { // If mapping does not have an @type, // set it to @id mapping['@type'] = mapping['@type'] || '@id'; // type mapping must be either @id or @vocab if(!['@id', '@vocab'].includes(mapping['@type'])) { throw new JsonLdError( 'Invalid JSON-LD syntax; container: @type requires @type to be ' + '@id or @vocab.', 'jsonld.SyntaxError', {code: 'invalid type mapping', context: localCtx}); } } } else { // in JSON-LD 1.0, container must not be an array (it must be a string, // which is one of the validContainers) isValid &= !_isArray(value['@container']); // check container length isValid &= container.length <= 1; } // check against valid containers isValid &= container.every(c => validContainers.includes(c)); // @set not allowed with @list isValid &= !(hasSet && container.includes('@list')); if(!isValid) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @container value must be ' + 'one of the following: ' + validContainers.join(', '), 'jsonld.SyntaxError', {code: 'invalid container mapping', context: localCtx}); } if(mapping.reverse && !container.every(c => ['@index', '@set'].includes(c))) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @container value for a @reverse ' + 'type definition must be @index or @set.', 'jsonld.SyntaxError', {code: 'invalid reverse property', context: localCtx}); } // add @container to mapping mapping['@container'] = container; } // property indexing if('@index' in value) { if(!('@container' in value) || !mapping['@container'].includes('@index')) { throw new JsonLdError( 'Invalid JSON-LD syntax; @index without @index in @container: ' + `"${value['@index']}" on term "${term}".`, 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } if(!_isString(value['@index']) || value['@index'].indexOf('@') === 0) { throw new JsonLdError( 'Invalid JSON-LD syntax; @index must expand to an IRI: ' + `"${value['@index']}" on term "${term}".`, 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } mapping['@index'] = value['@index']; } // scoped contexts if('@context' in value) { mapping['@context'] = value['@context']; } if('@language' in value && !('@type' in value)) { let language = value['@language']; if(language !== null && !_isString(language)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @language value must be ' + 'a string or null.', 'jsonld.SyntaxError', {code: 'invalid language mapping', context: localCtx}); } // add @language to mapping if(language !== null) { language = language.toLowerCase(); } mapping['@language'] = language; } // term may be used as a prefix if('@prefix' in value) { if(term.match(/:|\//)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @prefix used on a compact IRI term', 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } if(api.isKeyword(mapping['@id'])) { throw new JsonLdError( 'Invalid JSON-LD syntax; keywords may not be used as prefixes', 'jsonld.SyntaxError', {code: 'invalid term definition', context: localCtx}); } if(typeof value['@prefix'] === 'boolean') { mapping._prefix = value['@prefix'] === true; } else { throw new JsonLdError( 'Invalid JSON-LD syntax; @context value for @prefix must be boolean', 'jsonld.SyntaxError', {code: 'invalid @prefix value', context: localCtx}); } } if('@direction' in value) { const direction = value['@direction']; if(direction !== null && direction !== 'ltr' && direction !== 'rtl') { throw new JsonLdError( 'Invalid JSON-LD syntax; @direction value must be ' + 'null, "ltr", or "rtl".', 'jsonld.SyntaxError', {code: 'invalid base direction', context: localCtx}); } mapping['@direction'] = direction; } if('@nest' in value) { const nest = value['@nest']; if(!_isString(nest) || (nest !== '@nest' && nest.indexOf('@') === 0)) { throw new JsonLdError( 'Invalid JSON-LD syntax; @context @nest value must be ' + 'a string which is not a keyword other than @nest.', 'jsonld.SyntaxError', {code: 'invalid @nest value', context: localCtx}); } mapping['@nest'] = nest; } // disallow aliasing @context and @preserve const id = mapping['@id']; if(id === '@context' || id === '@preserve') { throw new JsonLdError( 'Invalid JSON-LD syntax; @context and @preserve cannot be aliased.', 'jsonld.SyntaxError', {code: 'invalid keyword alias', context: localCtx}); } // Check for overriding protected terms if(previousMapping && previousMapping.protected && !overrideProtected) { // force new term to continue to be protected and see if the mappings would // be equal activeCtx.protected[term] = true; mapping.protected = true; if(!_deepCompare(previousMapping, mapping)) { const protectedMode = (options && options.protectedMode) || 'error'; if(protectedMode === 'error') { throw new JsonLdError( 'Invalid JSON-LD syntax; tried to redefine a protected term.', 'jsonld.SyntaxError', {code: 'protected term redefinition', context: localCtx, term}); } else if(protectedMode === 'warn') { // FIXME: remove logging and use a handler console.warn('WARNING: protected term redefinition', {term}); return; } throw new JsonLdError( 'Invalid protectedMode.', 'jsonld.SyntaxError', {code: 'invalid protected mode', context: localCtx, term, protectedMode}); } } }; /** * Expands a string to a full IRI. The string may be a term, a prefix, a * relative IRI, or an absolute IRI. The associated absolute IRI will be * returned. * * @param activeCtx the current active context. * @param value the string to expand. * @param relativeTo options for how to resolve relative IRIs: * base: true to resolve against the base IRI, false not to. * vocab: true to concatenate after @vocab, false not to. * @param {Object} [options] - processing options. * * @return the expanded value. */ api.expandIri = (activeCtx, value, relativeTo, options) => { return _expandIri(activeCtx, value, relativeTo, undefined, undefined, options); }; /** * Expands a string to a full IRI. The string may be a term, a prefix, a * relative IRI, or an absolute IRI. The associated absolute IRI will be * returned. * * @param activeCtx the current active context. * @param value the string to expand. * @param relativeTo options for how to resolve relative IRIs: * base: true to resolve against the base IRI, false not to. * vocab: true to concatenate after @vocab, false not to. * @param localCtx the local context being processed (only given if called * during context processing). * @param defined a map for tracking cycles in context definitions (only given * if called during context processing). * @param {Object} [options] - processing options. * * @return the expanded value. */ function _expandIri(activeCtx, value, relativeTo, localCtx, defined, options) { // already expanded if(value === null || !_isString(value) || api.isKeyword(value)) { return value; } // ignore non-keyword things that look like a keyword if(value.match(KEYWORD_PATTERN)) { return null; } // define term dependency if not defined if(localCtx && localCtx.hasOwnProperty(value) && defined.get(value) !== true) { api.createTermDefinition({ activeCtx, localCtx, term: value, defined, options }); } relativeTo = relativeTo || {}; if(relativeTo.vocab) { const mapping = activeCtx.mappings.get(value); // value is explicitly ignored with a null mapping if(mapping === null) { return null; } if(_isObject(mapping) && '@id' in mapping) { // value is a term return mapping['@id']; } } // split value into prefix:suffix const colon = value.indexOf(':'); if(colon > 0) { const prefix = value.substr(0, colon); const suffix = value.substr(colon + 1); // do not expand blank nodes (prefix of '_') or already-absolute // IRIs (suffix of '//') if(prefix === '_' || suffix.indexOf('//') === 0) { return value; } // prefix dependency not defined, define it if(localCtx && localCtx.hasOwnProperty(prefix)) { api.createTermDefinition({ activeCtx, localCtx, term: prefix, defined, options }); } // use mapping if prefix is defined const mapping = activeCtx.mappings.get(prefix); if(mapping && mapping._prefix) { return mapping['@id'] + suffix; } // already absolute IRI if(_isAbsoluteIri(value)) { return value; } } // prepend vocab if(relativeTo.vocab && '@vocab' in activeCtx) { return activeCtx['@vocab'] + value; } // prepend base if(relativeTo.base && '@base' in activeCtx) { if(activeCtx['@base']) { // The null case preserves value as potentially relative return prependBase(prependBase(options.base, activeCtx['@base']), value); } } else if(relativeTo.base) { return prependBase(options.base, value); } return value; } /** * Gets the initial context. * * @param options the options to use: * [base] the document base IRI. * * @return the initial context. */ api.getInitialContext = options => { const key = JSON.stringify({processingMode: options.processingMode}); const cached = INITIAL_CONTEXT_CACHE.get(key); if(cached) { return cached; } const initialContext = { processingMode: options.processingMode, mappings: new Map(), inverse: null, getInverse: _createInverseContext, clone: _cloneActiveContext, revertToPreviousContext: _revertToPreviousContext, protected: {} }; // TODO: consider using LRU cache instead if(INITIAL_CONTEXT_CACHE.size === INITIAL_CONTEXT_CACHE_MAX_SIZE) { // clear whole cache -- assumes scenario where the cache fills means // the cache isn't being used very efficiently anyway INITIAL_CONTEXT_CACHE.clear(); } INITIAL_CONTEXT_CACHE.set(key, initialContext); return initialContext; /** * Generates an inverse context for use in the compaction algorithm, if * not already generated for the given active context. * * @return the inverse context. */ function _createInverseContext() { const activeCtx = this; // lazily create inverse if(activeCtx.inverse) { return activeCtx.inverse; } const inverse = activeCtx.inverse = {}; // variables for building fast CURIE map const fastCurieMap = activeCtx.fastCurieMap = {}; const irisToTerms = {}; // handle default language const defaultLanguage = (activeCtx['@language'] || '@none').toLowerCase(); // handle default direction const defaultDirection = activeCtx['@direction']; // create term selections for each mapping in the context, ordered by // shortest and then lexicographically least const mappings = activeCtx.mappings; const terms = [...mappings.keys()].sort(_compareShortestLeast); for(const term of terms) { const mapping = mappings.get(term); if(mapping === null) { continue; } let container = mapping['@container'] || '@none'; container = [].concat(container).sort().join(''); if(mapping['@id'] === null) { continue; } // iterate over every IRI in the mapping const ids = _asArray(mapping['@id']); for(const iri of ids) { let entry = inverse[iri]; const isKeyword = api.isKeyword(iri); if(!entry) { // initialize entry inverse[iri] = entry = {}; if(!isKeyword && !mapping._termHasColon) { // init IRI to term map and fast CURIE prefixes irisToTerms[iri] = [term]; const fastCurieEntry = {iri, terms: irisToTerms[iri]}; if(iri[0] in fastCurieMap) { fastCurieMap[iri[0]].push(fastCurieEntry); } else { fastCurieMap[iri[0]] = [fastCurieEntry]; } } } else if(!isKeyword && !mapping._termHasColon) { // add IRI to term match irisToTerms[iri].push(term); } // add new entry if(!entry[container]) { entry[container] = { '@language': {}, '@type': {}, '@any': {} }; } entry = entry[container]; _addPreferredTerm(term, entry['@any'], '@none'); if(mapping.reverse) { // term is preferred for values using @reverse _addPreferredTerm(term, entry['@type'], '@reverse'); } else if(mapping['@type'] === '@none') { _addPreferredTerm(term, entry['@any'], '@none'); _addPreferredTerm(term, entry['@language'], '@none'); _addPreferredTerm(term, entry['@type'], '@none'); } else if('@type' in mapping) { // term is preferred for values using specific type _addPreferredTerm(term, entry['@type'], mapping['@type']); } else if('@language' in mapping && '@direction' in mapping) { // term is preferred for values using specific language and direction const language = mapping['@language']; const direction = mapping['@direction']; if(language && direction) { _addPreferredTerm(term, entry['@language'], `${language}_${direction}`.toLowerCase()); } else if(language) { _addPreferredTerm(term, entry['@language'], language.toLowerCase()); } else if(direction) { _addPreferredTerm(term, entry['@language'], `_${direction}`); } else { _addPreferredTerm(term, entry['@language'], '@null'); } } else if('@language' in mapping) { _addPreferredTerm(term, entry['@language'], (mapping['@language'] || '@null').toLowerCase()); } else if('@direction' in mapping) { if(mapping['@direction']) { _addPreferredTerm(term, entry['@language'], `_${mapping['@direction']}`); } else { _addPreferredTerm(term, entry['@language'], '@none'); } } else if(defaultDirection) { _addPreferredTerm(term, entry['@language'], `_${defaultDirection}`); _addPreferredTerm(term, entry['@language'], '@none'); _addPreferredTerm(term, entry['@type'], '@none'); } else { // add entries for no type and no language _addPreferredTerm(term, entry['@language'], defaultLanguage); _addPreferredTerm(term, entry['@language'], '@none'); _addPreferredTerm(term, entry['@type'], '@none'); } } } // build fast CURIE map for(const key in fastCurieMap) { _buildIriMap(fastCurieMap, key, 1); } return inverse; } /** * Runs a recursive algorithm to build a lookup map for quickly finding * potential CURIEs. * * @param iriMap the map to build. * @param key the current key in the map to work on. * @param idx the index into the IRI to compare. */ function _buildIriMap(iriMap, key, idx) { const entries = iriMap[key]; const next = iriMap[key] = {}; let iri; let letter; for(const entry of entries) { iri = entry.iri; if(idx >= iri.length) { letter = ''; } else { letter = iri[idx]; } if(letter in next) { next[letter].push(entry); } else { next[letter] = [entry]; } } for(const key in next) { if(key === '') { continue; } _buildIriMap(next, key, idx + 1); } } /** * Adds the term for the given entry if not already added. * * @param term the term to add. * @param entry the inverse context typeOrLanguage entry to add to. * @param typeOrLanguageValue the key in the entry to add to. */ function _addPreferredTerm(term, entry, typeOrLanguageValue) { if(!entry.hasOwnProperty(typeOrLanguageValue)) { entry[typeOrLanguageValue] = term; } } /** * Clones an active context, creating a child active context. * * @return a clone (child) of the active context. */ function _cloneActiveContext() { const child = {}; child.mappings = util.clone(this.mappings); child.clone = this.clone; child.inverse = null; child.getInverse = this.getInverse; child.protected = util.clone(this.protected); if(this.previousContext) { child.previousContext = this.previousContext.clone(); } child.revertToPreviousContext = this.revertToPreviousContext; if('@base' in this) { child['@base'] = this['@base']; } if('@language' in this) { child['@language'] = this['@language']; } if('@vocab' in this) { child['@vocab'] = this['@vocab']; } return child; } /** * Reverts any type-scoped context in this active context to the previous * context. */ function _revertToPreviousContext() { if(!this.previousContext) { return this; } return this.previousContext.clone(); } }; /** * Gets the value for the given active context key and type, null if none is * set or undefined if none is set and type is '@context'. * * @param ctx the active context. * @param key the context key. * @param [type] the type of value to get (eg: '@id', '@type'), if not * specified gets the entire entry for a key, null if not found. * * @return the value, null, or undefined. */ api.getContextValue = (ctx, key, type) => { // invalid key if(key === null) { if(type === '@context') { return undefined; } return null; } // get specific entry information if(ctx.mappings.has(key)) { const entry = ctx.mappings.get(key); if(_isUndefined(type)) { // return whole entry return entry; } if(entry.hasOwnProperty(type)) { // return entry value for type return entry[type]; } } // get default language if(type === '@language' && type in ctx) { return ctx[type]; } // get default direction if(type === '@direction' && type in ctx) { return ctx[type]; } if(type === '@context') { return undefined; } return null; }; /** * Processing Mode check. * * @param activeCtx the current active context. * @param version the string or numeric version to check. * * @return boolean. */ api.processingMode = (activeCtx, version) => { if(version.toString() >= '1.1') { return !activeCtx.processingMode || activeCtx.processingMode >= 'json-ld-' + version.toString(); } else { return activeCtx.processingMode === 'json-ld-1.0'; } }; /** * Returns whether or not the given value is a keyword. * * @param v the value to check. * * @return true if the value is a keyword, false if not. */ api.isKeyword = v => { if(!_isString(v) || v[0] !== '@') { return false; } switch(v) { case '@base': case '@container': case '@context': case '@default': case '@direction': case '@embed': case '@explicit': case '@graph': case '@id': case '@included': case '@index': case '@json': case '@language': case '@list': case '@nest': case '@none': case '@omitDefault': case '@prefix': case '@preserve': case '@protected': case '@requireAll': case '@reverse': case '@set': case '@type': case '@value': case '@version': case '@vocab': return true; } return false; }; function _deepCompare(x1, x2) { // compare `null` or primitive types directly if((!(x1 && typeof x1 === 'object')) || (!(x2 && typeof x2 === 'object'))) { return x1 === x2; } // x1 and x2 are objects (also potentially arrays) const x1Array = Array.isArray(x1); if(x1Array !== Array.isArray(x2)) { return false; } if(x1Array) { if(x1.length !== x2.length) { return false; } for(let i = 0; i < x1.length; ++i) { if(!_deepCompare(x1[i], x2[i])) { return false; } } return true; } // x1 and x2 are non-array objects const k1s = Object.keys(x1); const k2s = Object.keys(x2); if(k1s.length !== k2s.length) { return false; } for(const k1 in x1) { let v1 = x1[k1]; let v2 = x2[k1]; // special case: `@container` can be in any order if(k1 === '@container') { if(Array.isArray(v1) && Array.isArray(v2)) { v1 = v1.slice().sort(); v2 = v2.slice().sort(); } } if(!_deepCompare(v1, v2)) { return false; } } return true; } /***/ }), /***/ "./node_modules/jsonld/lib/documentLoaders/node.js": /*!*********************************************************!*\ !*** ./node_modules/jsonld/lib/documentLoaders/node.js ***! \*********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const {parseLinkHeader, buildHeaders} = __webpack_require__(/*! ../util */ "./node_modules/jsonld/lib/util.js"); const {LINK_HEADER_CONTEXT} = __webpack_require__(/*! ../constants */ "./node_modules/jsonld/lib/constants.js"); const JsonLdError = __webpack_require__(/*! ../JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const RequestQueue = __webpack_require__(/*! ../RequestQueue */ "./node_modules/jsonld/lib/RequestQueue.js"); const {prependBase} = __webpack_require__(/*! ../url */ "./node_modules/jsonld/lib/url.js"); /** * Creates a built-in node document loader. * * @param options the options to use: * secure: require all URLs to use HTTPS. * strictSSL: true to require SSL certificates to be valid, * false not to (default: true). * maxRedirects: the maximum number of redirects to permit, none by * default. * request: the object which will make the request, default is * provided by `https://www.npmjs.com/package/request`. * headers: an object (map) of headers which will be passed as request * headers for the requested document. Accept is not allowed. * * @return the node document loader. */ module.exports = ({ secure, strictSSL = true, maxRedirects = -1, request, headers = {} } = {strictSSL: true, maxRedirects: -1, headers: {}}) => { headers = buildHeaders(headers); // TODO: use `axios` request = request || __webpack_require__(/*! request */ 2); const http = __webpack_require__(/*! http */ 3); const queue = new RequestQueue(); return queue.wrapLoader(function(url) { return loadDocument(url, []); }); async function loadDocument(url, redirects) { if(url.indexOf('http:') !== 0 && url.indexOf('https:') !== 0) { throw new JsonLdError( 'URL could not be dereferenced; only "http" and "https" URLs are ' + 'supported.', 'jsonld.InvalidUrl', {code: 'loading document failed', url}); } if(secure && url.indexOf('https') !== 0) { throw new JsonLdError( 'URL could not be dereferenced; secure mode is enabled and ' + 'the URL\'s scheme is not "https".', 'jsonld.InvalidUrl', {code: 'loading document failed', url}); } // TODO: disable cache until HTTP caching implemented let doc = null;//cache.get(url); if(doc !== null) { return doc; } let result; let alternate = null; try { result = await _request(request, { url, headers, strictSSL, followRedirect: false }); } catch(e) { throw new JsonLdError( 'URL could not be dereferenced, an error occurred.', 'jsonld.LoadDocumentError', {code: 'loading document failed', url, cause: e}); } const {res, body} = result; doc = {contextUrl: null, documentUrl: url, document: body || null}; // handle error const statusText = http.STATUS_CODES[res.statusCode]; if(res.statusCode >= 400) { throw new JsonLdError( `URL "${url}" could not be dereferenced: ${statusText}`, 'jsonld.InvalidUrl', { code: 'loading document failed', url, httpStatusCode: res.statusCode }); } // handle Link Header if(res.headers.link && res.headers['content-type'] !== 'application/ld+json') { // only 1 related link header permitted const linkHeaders = parseLinkHeader(res.headers.link); const linkedContext = linkHeaders[LINK_HEADER_CONTEXT]; if(Array.isArray(linkedContext)) { throw new JsonLdError( 'URL could not be dereferenced, it has more than one associated ' + 'HTTP Link Header.', 'jsonld.InvalidUrl', {code: 'multiple context link headers', url}); } if(linkedContext) { doc.contextUrl = linkedContext.target; } // "alternate" link header is a redirect alternate = linkHeaders['alternate']; if(alternate && alternate.type == 'application/ld+json' && !(res.headers['content-type'] || '') .match(/^application\/(\w*\+)?json$/)) { res.headers.location = prependBase(url, alternate.target); } } // handle redirect if((alternate || res.statusCode >= 300 && res.statusCode < 400) && res.headers.location) { if(redirects.length === maxRedirects) { throw new JsonLdError( 'URL could not be dereferenced; there were too many redirects.', 'jsonld.TooManyRedirects', { code: 'loading document failed', url, httpStatusCode: res.statusCode, redirects }); } if(redirects.indexOf(url) !== -1) { throw new JsonLdError( 'URL could not be dereferenced; infinite redirection was detected.', 'jsonld.InfiniteRedirectDetected', { code: 'recursive context inclusion', url, httpStatusCode: res.statusCode, redirects }); } redirects.push(url); return loadDocument(res.headers.location, redirects); } // cache for each redirected URL redirects.push(url); // TODO: disable cache until HTTP caching implemented /* for(let i = 0; i < redirects.length; ++i) { cache.set( redirects[i], {contextUrl: null, documentUrl: redirects[i], document: body}); } */ return doc; } }; function _request(request, options) { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if(err) { reject(err); } else { resolve({res, body}); } }); }); } /***/ }), /***/ "./node_modules/jsonld/lib/documentLoaders/xhr.js": /*!********************************************************!*\ !*** ./node_modules/jsonld/lib/documentLoaders/xhr.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const {parseLinkHeader, buildHeaders} = __webpack_require__(/*! ../util */ "./node_modules/jsonld/lib/util.js"); const {LINK_HEADER_CONTEXT} = __webpack_require__(/*! ../constants */ "./node_modules/jsonld/lib/constants.js"); const JsonLdError = __webpack_require__(/*! ../JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const RequestQueue = __webpack_require__(/*! ../RequestQueue */ "./node_modules/jsonld/lib/RequestQueue.js"); const {prependBase} = __webpack_require__(/*! ../url */ "./node_modules/jsonld/lib/url.js"); const REGEX_LINK_HEADER = /(^|(\r\n))link:/i; /** * Creates a built-in XMLHttpRequest document loader. * * @param options the options to use: * secure: require all URLs to use HTTPS. * headers: an object (map) of headers which will be passed as request * headers for the requested document. Accept is not allowed. * [xhr]: the XMLHttpRequest API to use. * * @return the XMLHttpRequest document loader. */ module.exports = ({ secure, headers = {}, xhr } = {headers: {}}) => { headers = buildHeaders(headers); const queue = new RequestQueue(); return queue.wrapLoader(loader); async function loader(url) { if(url.indexOf('http:') !== 0 && url.indexOf('https:') !== 0) { throw new JsonLdError( 'URL could not be dereferenced; only "http" and "https" URLs are ' + 'supported.', 'jsonld.InvalidUrl', {code: 'loading document failed', url}); } if(secure && url.indexOf('https') !== 0) { throw new JsonLdError( 'URL could not be dereferenced; secure mode is enabled and ' + 'the URL\'s scheme is not "https".', 'jsonld.InvalidUrl', {code: 'loading document failed', url}); } let req; try { req = await _get(xhr, url, headers); } catch(e) { throw new JsonLdError( 'URL could not be dereferenced, an error occurred.', 'jsonld.LoadDocumentError', {code: 'loading document failed', url, cause: e}); } if(req.status >= 400) { throw new JsonLdError( 'URL could not be dereferenced: ' + req.statusText, 'jsonld.LoadDocumentError', { code: 'loading document failed', url, httpStatusCode: req.status }); } let doc = {contextUrl: null, documentUrl: url, document: req.response}; let alternate = null; // handle Link Header (avoid unsafe header warning by existence testing) const contentType = req.getResponseHeader('Content-Type'); let linkHeader; if(REGEX_LINK_HEADER.test(req.getAllResponseHeaders())) { linkHeader = req.getResponseHeader('Link'); } if(linkHeader && contentType !== 'application/ld+json') { // only 1 related link header permitted const linkHeaders = parseLinkHeader(linkHeader); const linkedContext = linkHeaders[LINK_HEADER_CONTEXT]; if(Array.isArray(linkedContext)) { throw new JsonLdError( 'URL could not be dereferenced, it has more than one ' + 'associated HTTP Link Header.', 'jsonld.InvalidUrl', {code: 'multiple context link headers', url}); } if(linkedContext) { doc.contextUrl = linkedContext.target; } // "alternate" link header is a redirect alternate = linkHeaders['alternate']; if(alternate && alternate.type == 'application/ld+json' && !(contentType || '').match(/^application\/(\w*\+)?json$/)) { doc = await loader(prependBase(url, alternate.target)); } } return doc; } }; function _get(xhr, url, headers) { xhr = xhr || XMLHttpRequest; const req = new xhr(); return new Promise((resolve, reject) => { req.onload = () => resolve(req); req.onerror = err => reject(err); req.open('GET', url, true); for(const k in headers) { req.setRequestHeader(k, headers[k]); } req.send(); }); } /***/ }), /***/ "./node_modules/jsonld/lib/expand.js": /*!*******************************************!*\ !*** ./node_modules/jsonld/lib/expand.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const { isArray: _isArray, isObject: _isObject, isEmptyObject: _isEmptyObject, isString: _isString, isUndefined: _isUndefined } = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const { isList: _isList, isValue: _isValue, isGraph: _isGraph, isSubject: _isSubject } = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const { expandIri: _expandIri, getContextValue: _getContextValue, isKeyword: _isKeyword, process: _processContext, processingMode: _processingMode } = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const { isAbsolute: _isAbsoluteIri } = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const { addValue: _addValue, asArray: _asArray, getValues: _getValues, validateTypeValue: _validateTypeValue } = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const api = {}; module.exports = api; const REGEX_BCP47 = /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/; /** * Recursively expands an element using the given context. Any context in * the element will be removed. All context URLs must have been retrieved * before calling this method. * * @param activeCtx the context to use. * @param activeProperty the property for the element, null for none. * @param element the element to expand. * @param options the expansion options. * @param insideList true if the element is a list, false if not. * @param insideIndex true if the element is inside an index container, * false if not. * @param typeScopedContext an optional type-scoped active context for * expanding values of nodes that were expressed according to * a type-scoped context. * @param expansionMap(info) a function that can be used to custom map * unmappable values (or to throw an error when they are detected); * if this function returns `undefined` then the default behavior * will be used. * * @return a Promise that resolves to the expanded value. */ api.expand = async ({ activeCtx, activeProperty = null, element, options = {}, insideList = false, insideIndex = false, typeScopedContext = null, expansionMap = () => undefined }) => { // nothing to expand if(element === null || element === undefined) { return null; } // disable framing if activeProperty is @default if(activeProperty === '@default') { options = Object.assign({}, options, {isFrame: false}); } if(!_isArray(element) && !_isObject(element)) { // drop free-floating scalars that are not in lists unless custom mapped if(!insideList && (activeProperty === null || _expandIri(activeCtx, activeProperty, {vocab: true}, options) === '@graph')) { const mapped = await expansionMap({ unmappedValue: element, activeCtx, activeProperty, options, insideList }); if(mapped === undefined) { return null; } return mapped; } // expand element according to value expansion rules return _expandValue({activeCtx, activeProperty, value: element, options}); } // recursively expand array if(_isArray(element)) { let rval = []; const container = _getContextValue( activeCtx, activeProperty, '@container') || []; insideList = insideList || container.includes('@list'); for(let i = 0; i < element.length; ++i) { // expand element let e = await api.expand({ activeCtx, activeProperty, element: element[i], options, expansionMap, insideIndex, typeScopedContext }); if(insideList && _isArray(e)) { e = {'@list': e}; } if(e === null) { e = await expansionMap({ unmappedValue: element[i], activeCtx, activeProperty, parent: element, index: i, options, expandedParent: rval, insideList }); if(e === undefined) { continue; } } if(_isArray(e)) { rval = rval.concat(e); } else { rval.push(e); } } return rval; } // recursively expand object: // first, expand the active property const expandedActiveProperty = _expandIri( activeCtx, activeProperty, {vocab: true}, options); // Get any property-scoped context for activeProperty const propertyScopedCtx = _getContextValue(activeCtx, activeProperty, '@context'); // second, determine if any type-scoped context should be reverted; it // should only be reverted when the following are all true: // 1. `element` is not a value or subject reference // 2. `insideIndex` is false typeScopedContext = typeScopedContext || (activeCtx.previousContext ? activeCtx : null); let keys = Object.keys(element).sort(); let mustRevert = !insideIndex; if(mustRevert && typeScopedContext && keys.length <= 2 && !keys.includes('@context')) { for(const key of keys) { const expandedProperty = _expandIri( typeScopedContext, key, {vocab: true}, options); if(expandedProperty === '@value') { // value found, ensure type-scoped context is used to expand it mustRevert = false; activeCtx = typeScopedContext; break; } if(expandedProperty === '@id' && keys.length === 1) { // subject reference found, do not revert mustRevert = false; break; } } } if(mustRevert) { // revert type scoped context activeCtx = activeCtx.revertToPreviousContext(); } // apply property-scoped context after reverting term-scoped context if(!_isUndefined(propertyScopedCtx)) { activeCtx = await _processContext({ activeCtx, localCtx: propertyScopedCtx, propagate: true, overrideProtected: true, options }); } // if element has a context, process it if('@context' in element) { activeCtx = await _processContext( {activeCtx, localCtx: element['@context'], options}); } // set the type-scoped context to the context on input, for use later typeScopedContext = activeCtx; // Remember the first key found expanding to @type let typeKey = null; // look for scoped contexts on `@type` for(const key of keys) { const expandedProperty = _expandIri(activeCtx, key, {vocab: true}, options); if(expandedProperty === '@type') { // set scoped contexts from @type // avoid sorting if possible typeKey = typeKey || key; const value = element[key]; const types = Array.isArray(value) ? (value.length > 1 ? value.slice().sort() : value) : [value]; for(const type of types) { const ctx = _getContextValue(typeScopedContext, type, '@context'); if(!_isUndefined(ctx)) { activeCtx = await _processContext({ activeCtx, localCtx: ctx, options, propagate: false }); } } } } // process each key and value in element, ignoring @nest content let rval = {}; await _expandObject({ activeCtx, activeProperty, expandedActiveProperty, element, expandedParent: rval, options, insideList, typeKey, typeScopedContext, expansionMap}); // get property count on expanded output keys = Object.keys(rval); let count = keys.length; if('@value' in rval) { // @value must only have @language or @type if('@type' in rval && ('@language' in rval || '@direction' in rval)) { throw new JsonLdError( 'Invalid JSON-LD syntax; an element containing "@value" may not ' + 'contain both "@type" and either "@language" or "@direction".', 'jsonld.SyntaxError', {code: 'invalid value object', element: rval}); } let validCount = count - 1; if('@type' in rval) { validCount -= 1; } if('@index' in rval) { validCount -= 1; } if('@language' in rval) { validCount -= 1; } if('@direction' in rval) { validCount -= 1; } if(validCount !== 0) { throw new JsonLdError( 'Invalid JSON-LD syntax; an element containing "@value" may only ' + 'have an "@index" property and either "@type" ' + 'or either or both "@language" or "@direction".', 'jsonld.SyntaxError', {code: 'invalid value object', element: rval}); } const values = rval['@value'] === null ? [] : _asArray(rval['@value']); const types = _getValues(rval, '@type'); // drop null @values unless custom mapped if(_processingMode(activeCtx, 1.1) && types.includes('@json') && types.length === 1) { // Any value of @value is okay if @type: @json } else if(values.length === 0) { const mapped = await expansionMap({ unmappedValue: rval, activeCtx, activeProperty, element, options, insideList }); if(mapped !== undefined) { rval = mapped; } else { rval = null; } } else if(!values.every(v => (_isString(v) || _isEmptyObject(v))) && '@language' in rval) { // if @language is present, @value must be a string throw new JsonLdError( 'Invalid JSON-LD syntax; only strings may be language-tagged.', 'jsonld.SyntaxError', {code: 'invalid language-tagged value', element: rval}); } else if(!types.every(t => (_isAbsoluteIri(t) && !(_isString(t) && t.indexOf('_:') === 0) || _isEmptyObject(t)))) { throw new JsonLdError( 'Invalid JSON-LD syntax; an element containing "@value" and "@type" ' + 'must have an absolute IRI for the value of "@type".', 'jsonld.SyntaxError', {code: 'invalid typed value', element: rval}); } } else if('@type' in rval && !_isArray(rval['@type'])) { // convert @type to an array rval['@type'] = [rval['@type']]; } else if('@set' in rval || '@list' in rval) { // handle @set and @list if(count > 1 && !(count === 2 && '@index' in rval)) { throw new JsonLdError( 'Invalid JSON-LD syntax; if an element has the property "@set" ' + 'or "@list", then it can have at most one other property that is ' + '"@index".', 'jsonld.SyntaxError', {code: 'invalid set or list object', element: rval}); } // optimize away @set if('@set' in rval) { rval = rval['@set']; keys = Object.keys(rval); count = keys.length; } } else if(count === 1 && '@language' in rval) { // drop objects with only @language unless custom mapped const mapped = await expansionMap(rval, { unmappedValue: rval, activeCtx, activeProperty, element, options, insideList }); if(mapped !== undefined) { rval = mapped; } else { rval = null; } } // drop certain top-level objects that do not occur in lists, unless custom // mapped if(_isObject(rval) && !options.keepFreeFloatingNodes && !insideList && (activeProperty === null || expandedActiveProperty === '@graph')) { // drop empty object, top-level @value/@list, or object with only @id if(count === 0 || '@value' in rval || '@list' in rval || (count === 1 && '@id' in rval)) { const mapped = await expansionMap({ unmappedValue: rval, activeCtx, activeProperty, element, options, insideList }); if(mapped !== undefined) { rval = mapped; } else { rval = null; } } } return rval; }; /** * Expand each key and value of element adding to result * * @param activeCtx the context to use. * @param activeProperty the property for the element. * @param expandedActiveProperty the expansion of activeProperty * @param element the element to expand. * @param expandedParent the expanded result into which to add values. * @param options the expansion options. * @param insideList true if the element is a list, false if not. * @param typeKey first key found expanding to @type. * @param typeScopedContext the context before reverting. * @param expansionMap(info) a function that can be used to custom map * unmappable values (or to throw an error when they are detected); * if this function returns `undefined` then the default behavior * will be used. */ async function _expandObject({ activeCtx, activeProperty, expandedActiveProperty, element, expandedParent, options = {}, insideList, typeKey, typeScopedContext, expansionMap }) { const keys = Object.keys(element).sort(); const nests = []; let unexpandedValue; // Figure out if this is the type for a JSON literal const isJsonType = element[typeKey] && _expandIri(activeCtx, (_isArray(element[typeKey]) ? element[typeKey][0] : element[typeKey]), {vocab: true}, options) === '@json'; for(const key of keys) { let value = element[key]; let expandedValue; // skip @context if(key === '@context') { continue; } // expand property let expandedProperty = _expandIri(activeCtx, key, {vocab: true}, options); // drop non-absolute IRI keys that aren't keywords unless custom mapped if(expandedProperty === null || !(_isAbsoluteIri(expandedProperty) || _isKeyword(expandedProperty))) { // TODO: use `await` to support async expandedProperty = expansionMap({ unmappedProperty: key, activeCtx, activeProperty, parent: element, options, insideList, value, expandedParent }); if(expandedProperty === undefined) { continue; } } if(_isKeyword(expandedProperty)) { if(expandedActiveProperty === '@reverse') { throw new JsonLdError( 'Invalid JSON-LD syntax; a keyword cannot be used as a @reverse ' + 'property.', 'jsonld.SyntaxError', {code: 'invalid reverse property map', value}); } if(expandedProperty in expandedParent && expandedProperty !== '@included' && expandedProperty !== '@type') { throw new JsonLdError( 'Invalid JSON-LD syntax; colliding keywords detected.', 'jsonld.SyntaxError', {code: 'colliding keywords', keyword: expandedProperty}); } } // syntax error if @id is not a string if(expandedProperty === '@id') { if(!_isString(value)) { if(!options.isFrame) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@id" value must a string.', 'jsonld.SyntaxError', {code: 'invalid @id value', value}); } if(_isObject(value)) { // empty object is a wildcard if(!_isEmptyObject(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@id" value an empty object or array ' + 'of strings, if framing', 'jsonld.SyntaxError', {code: 'invalid @id value', value}); } } else if(_isArray(value)) { if(!value.every(v => _isString(v))) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@id" value an empty object or array ' + 'of strings, if framing', 'jsonld.SyntaxError', {code: 'invalid @id value', value}); } } else { throw new JsonLdError( 'Invalid JSON-LD syntax; "@id" value an empty object or array ' + 'of strings, if framing', 'jsonld.SyntaxError', {code: 'invalid @id value', value}); } } _addValue( expandedParent, '@id', _asArray(value).map(v => _isString(v) ? _expandIri(activeCtx, v, {base: true}, options) : v), {propertyIsArray: options.isFrame}); continue; } if(expandedProperty === '@type') { // if framing, can be a default object, but need to expand // key to determine that if(_isObject(value)) { value = Object.fromEntries(Object.entries(value).map(([k, v]) => [ _expandIri(typeScopedContext, k, {vocab: true}), _asArray(v).map(vv => _expandIri(typeScopedContext, vv, {base: true, vocab: true}) ) ])); } _validateTypeValue(value, options.isFrame); _addValue( expandedParent, '@type', _asArray(value).map(v => _isString(v) ? _expandIri(typeScopedContext, v, {base: true, vocab: true}, options) : v), {propertyIsArray: options.isFrame}); continue; } // Included blocks are treated as an array of separate object nodes sharing // the same referencing active_property. // For 1.0, it is skipped as are other unknown keywords if(expandedProperty === '@included' && _processingMode(activeCtx, 1.1)) { const includedResult = _asArray(await api.expand({ activeCtx, activeProperty, element: value, options, expansionMap })); // Expanded values must be node objects if(!includedResult.every(v => _isSubject(v))) { throw new JsonLdError( 'Invalid JSON-LD syntax; ' + 'values of @included must expand to node objects.', 'jsonld.SyntaxError', {code: 'invalid @included value', value}); } _addValue( expandedParent, '@included', includedResult, {propertyIsArray: true}); continue; } // @graph must be an array or an object if(expandedProperty === '@graph' && !(_isObject(value) || _isArray(value))) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@graph" value must not be an ' + 'object or an array.', 'jsonld.SyntaxError', {code: 'invalid @graph value', value}); } if(expandedProperty === '@value') { // capture value for later // "colliding keywords" check prevents this from being set twice unexpandedValue = value; if(isJsonType && _processingMode(activeCtx, 1.1)) { // no coercion to array, and retain all values expandedParent['@value'] = value; } else { _addValue( expandedParent, '@value', value, {propertyIsArray: options.isFrame}); } continue; } // @language must be a string // it should match BCP47 if(expandedProperty === '@language') { if(value === null) { // drop null @language values, they expand as if they didn't exist continue; } if(!_isString(value) && !options.isFrame) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@language" value must be a string.', 'jsonld.SyntaxError', {code: 'invalid language-tagged string', value}); } // ensure language value is lowercase value = _asArray(value).map(v => _isString(v) ? v.toLowerCase() : v); // ensure language tag matches BCP47 for(const lang of value) { if(_isString(lang) && !lang.match(REGEX_BCP47)) { console.warn(`@language must be valid BCP47: ${lang}`); } } _addValue( expandedParent, '@language', value, {propertyIsArray: options.isFrame}); continue; } // @direction must be "ltr" or "rtl" if(expandedProperty === '@direction') { if(!_isString(value) && !options.isFrame) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@direction" value must be a string.', 'jsonld.SyntaxError', {code: 'invalid base direction', value}); } value = _asArray(value); // ensure direction is "ltr" or "rtl" for(const dir of value) { if(_isString(dir) && dir !== 'ltr' && dir !== 'rtl') { throw new JsonLdError( 'Invalid JSON-LD syntax; "@direction" must be "ltr" or "rtl".', 'jsonld.SyntaxError', {code: 'invalid base direction', value}); } } _addValue( expandedParent, '@direction', value, {propertyIsArray: options.isFrame}); continue; } // @index must be a string if(expandedProperty === '@index') { if(!_isString(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@index" value must be a string.', 'jsonld.SyntaxError', {code: 'invalid @index value', value}); } _addValue(expandedParent, '@index', value); continue; } // @reverse must be an object if(expandedProperty === '@reverse') { if(!_isObject(value)) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@reverse" value must be an object.', 'jsonld.SyntaxError', {code: 'invalid @reverse value', value}); } expandedValue = await api.expand({ activeCtx, activeProperty: '@reverse', element: value, options, expansionMap }); // properties double-reversed if('@reverse' in expandedValue) { for(const property in expandedValue['@reverse']) { _addValue( expandedParent, property, expandedValue['@reverse'][property], {propertyIsArray: true}); } } // FIXME: can this be merged with code below to simplify? // merge in all reversed properties let reverseMap = expandedParent['@reverse'] || null; for(const property in expandedValue) { if(property === '@reverse') { continue; } if(reverseMap === null) { reverseMap = expandedParent['@reverse'] = {}; } _addValue(reverseMap, property, [], {propertyIsArray: true}); const items = expandedValue[property]; for(let ii = 0; ii < items.length; ++ii) { const item = items[ii]; if(_isValue(item) || _isList(item)) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@reverse" value must not be a ' + '@value or an @list.', 'jsonld.SyntaxError', {code: 'invalid reverse property value', value: expandedValue}); } _addValue(reverseMap, property, item, {propertyIsArray: true}); } } continue; } // nested keys if(expandedProperty === '@nest') { nests.push(key); continue; } // use potential scoped context for key let termCtx = activeCtx; const ctx = _getContextValue(activeCtx, key, '@context'); if(!_isUndefined(ctx)) { termCtx = await _processContext({ activeCtx, localCtx: ctx, propagate: true, overrideProtected: true, options }); } const container = _getContextValue(termCtx, key, '@container') || []; if(container.includes('@language') && _isObject(value)) { const direction = _getContextValue(termCtx, key, '@direction'); // handle language map container (skip if value is not an object) expandedValue = _expandLanguageMap(termCtx, value, direction, options); } else if(container.includes('@index') && _isObject(value)) { // handle index container (skip if value is not an object) const asGraph = container.includes('@graph'); const indexKey = _getContextValue(termCtx, key, '@index') || '@index'; const propertyIndex = indexKey !== '@index' && _expandIri(activeCtx, indexKey, {vocab: true}, options); expandedValue = await _expandIndexMap({ activeCtx: termCtx, options, activeProperty: key, value, expansionMap, asGraph, indexKey, propertyIndex }); } else if(container.includes('@id') && _isObject(value)) { // handle id container (skip if value is not an object) const asGraph = container.includes('@graph'); expandedValue = await _expandIndexMap({ activeCtx: termCtx, options, activeProperty: key, value, expansionMap, asGraph, indexKey: '@id' }); } else if(container.includes('@type') && _isObject(value)) { // handle type container (skip if value is not an object) expandedValue = await _expandIndexMap({ // since container is `@type`, revert type scoped context when expanding activeCtx: termCtx.revertToPreviousContext(), options, activeProperty: key, value, expansionMap, asGraph: false, indexKey: '@type' }); } else { // recurse into @list or @set const isList = (expandedProperty === '@list'); if(isList || expandedProperty === '@set') { let nextActiveProperty = activeProperty; if(isList && expandedActiveProperty === '@graph') { nextActiveProperty = null; } expandedValue = await api.expand({ activeCtx: termCtx, activeProperty: nextActiveProperty, element: value, options, insideList: isList, expansionMap }); } else if( _getContextValue(activeCtx, key, '@type') === '@json') { expandedValue = { '@type': '@json', '@value': value }; } else { // recursively expand value with key as new active property expandedValue = await api.expand({ activeCtx: termCtx, activeProperty: key, element: value, options, insideList: false, expansionMap }); } } // drop null values if property is not @value if(expandedValue === null && expandedProperty !== '@value') { // TODO: use `await` to support async expandedValue = expansionMap({ unmappedValue: value, expandedProperty, activeCtx: termCtx, activeProperty, parent: element, options, insideList, key, expandedParent }); if(expandedValue === undefined) { continue; } } // convert expanded value to @list if container specifies it if(expandedProperty !== '@list' && !_isList(expandedValue) && container.includes('@list')) { // ensure expanded value in @list is an array expandedValue = {'@list': _asArray(expandedValue)}; } // convert expanded value to @graph if container specifies it // and value is not, itself, a graph // index cases handled above if(container.includes('@graph') && !container.some(key => key === '@id' || key === '@index')) { // ensure expanded values are arrays expandedValue = _asArray(expandedValue) .map(v => ({'@graph': _asArray(v)})); } // FIXME: can this be merged with code above to simplify? // merge in reverse properties if(termCtx.mappings.has(key) && termCtx.mappings.get(key).reverse) { const reverseMap = expandedParent['@reverse'] = expandedParent['@reverse'] || {}; expandedValue = _asArray(expandedValue); for(let ii = 0; ii < expandedValue.length; ++ii) { const item = expandedValue[ii]; if(_isValue(item) || _isList(item)) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@reverse" value must not be a ' + '@value or an @list.', 'jsonld.SyntaxError', {code: 'invalid reverse property value', value: expandedValue}); } _addValue(reverseMap, expandedProperty, item, {propertyIsArray: true}); } continue; } // add value for property // special keywords handled above _addValue(expandedParent, expandedProperty, expandedValue, { propertyIsArray: true }); } // @value must not be an object or an array (unless framing) or if @type is // @json if('@value' in expandedParent) { if(expandedParent['@type'] === '@json' && _processingMode(activeCtx, 1.1)) { // allow any value, to be verified when the object is fully expanded and // the @type is @json. } else if((_isObject(unexpandedValue) || _isArray(unexpandedValue)) && !options.isFrame) { throw new JsonLdError( 'Invalid JSON-LD syntax; "@value" value must not be an ' + 'object or an array.', 'jsonld.SyntaxError', {code: 'invalid value object value', value: unexpandedValue}); } } // expand each nested key for(const key of nests) { const nestedValues = _isArray(element[key]) ? element[key] : [element[key]]; for(const nv of nestedValues) { if(!_isObject(nv) || Object.keys(nv).some(k => _expandIri(activeCtx, k, {vocab: true}, options) === '@value')) { throw new JsonLdError( 'Invalid JSON-LD syntax; nested value must be a node object.', 'jsonld.SyntaxError', {code: 'invalid @nest value', value: nv}); } await _expandObject({ activeCtx, activeProperty, expandedActiveProperty, element: nv, expandedParent, options, insideList, typeScopedContext, typeKey, expansionMap}); } } } /** * Expands the given value by using the coercion and keyword rules in the * given context. * * @param activeCtx the active context to use. * @param activeProperty the active property the value is associated with. * @param value the value to expand. * @param {Object} [options] - processing options. * * @return the expanded value. */ function _expandValue({activeCtx, activeProperty, value, options}) { // nothing to expand if(value === null || value === undefined) { return null; } // special-case expand @id and @type (skips '@id' expansion) const expandedProperty = _expandIri( activeCtx, activeProperty, {vocab: true}, options); if(expandedProperty === '@id') { return _expandIri(activeCtx, value, {base: true}, options); } else if(expandedProperty === '@type') { return _expandIri(activeCtx, value, {vocab: true, base: true}, options); } // get type definition from context const type = _getContextValue(activeCtx, activeProperty, '@type'); // do @id expansion (automatic for @graph) if((type === '@id' || expandedProperty === '@graph') && _isString(value)) { return {'@id': _expandIri(activeCtx, value, {base: true}, options)}; } // do @id expansion w/vocab if(type === '@vocab' && _isString(value)) { return { '@id': _expandIri(activeCtx, value, {vocab: true, base: true}, options) }; } // do not expand keyword values if(_isKeyword(expandedProperty)) { return value; } const rval = {}; if(type && !['@id', '@vocab', '@none'].includes(type)) { // other type rval['@type'] = type; } else if(_isString(value)) { // check for language tagging for strings const language = _getContextValue(activeCtx, activeProperty, '@language'); if(language !== null) { rval['@language'] = language; } const direction = _getContextValue(activeCtx, activeProperty, '@direction'); if(direction !== null) { rval['@direction'] = direction; } } // do conversion of values that aren't basic JSON types to strings if(!['boolean', 'number', 'string'].includes(typeof value)) { value = value.toString(); } rval['@value'] = value; return rval; } /** * Expands a language map. * * @param activeCtx the active context to use. * @param languageMap the language map to expand. * @param direction the direction to apply to values. * @param {Object} [options] - processing options. * * @return the expanded language map. */ function _expandLanguageMap(activeCtx, languageMap, direction, options) { const rval = []; const keys = Object.keys(languageMap).sort(); for(const key of keys) { const expandedKey = _expandIri(activeCtx, key, {vocab: true}, options); let val = languageMap[key]; if(!_isArray(val)) { val = [val]; } for(const item of val) { if(item === null) { // null values are allowed (8.5) but ignored (3.1) continue; } if(!_isString(item)) { throw new JsonLdError( 'Invalid JSON-LD syntax; language map values must be strings.', 'jsonld.SyntaxError', {code: 'invalid language map value', languageMap}); } const val = {'@value': item}; if(expandedKey !== '@none') { val['@language'] = key.toLowerCase(); } if(direction) { val['@direction'] = direction; } rval.push(val); } } return rval; } async function _expandIndexMap( {activeCtx, options, activeProperty, value, expansionMap, asGraph, indexKey, propertyIndex}) { const rval = []; const keys = Object.keys(value).sort(); const isTypeIndex = indexKey === '@type'; for(let key of keys) { // if indexKey is @type, there may be a context defined for it if(isTypeIndex) { const ctx = _getContextValue(activeCtx, key, '@context'); if(!_isUndefined(ctx)) { activeCtx = await _processContext({ activeCtx, localCtx: ctx, propagate: false, options }); } } let val = value[key]; if(!_isArray(val)) { val = [val]; } val = await api.expand({ activeCtx, activeProperty, element: val, options, insideList: false, insideIndex: true, expansionMap }); // expand for @type, but also for @none let expandedKey; if(propertyIndex) { if(key === '@none') { expandedKey = '@none'; } else { expandedKey = _expandValue( {activeCtx, activeProperty: indexKey, value: key, options}); } } else { expandedKey = _expandIri(activeCtx, key, {vocab: true}, options); } if(indexKey === '@id') { // expand document relative key = _expandIri(activeCtx, key, {base: true}, options); } else if(isTypeIndex) { key = expandedKey; } for(let item of val) { // If this is also a @graph container, turn items into graphs if(asGraph && !_isGraph(item)) { item = {'@graph': [item]}; } if(indexKey === '@type') { if(expandedKey === '@none') { // ignore @none } else if(item['@type']) { item['@type'] = [key].concat(item['@type']); } else { item['@type'] = [key]; } } else if(_isValue(item) && !['@language', '@type', '@index'].includes(indexKey)) { throw new JsonLdError( 'Invalid JSON-LD syntax; Attempt to add illegal key to value ' + `object: "${indexKey}".`, 'jsonld.SyntaxError', {code: 'invalid value object', value: item}); } else if(propertyIndex) { // index is a property to be expanded, and values interpreted for that // property if(expandedKey !== '@none') { // expand key as a value _addValue(item, propertyIndex, expandedKey, { propertyIsArray: true, prependValue: true }); } } else if(expandedKey !== '@none' && !(indexKey in item)) { item[indexKey] = key; } rval.push(item); } } return rval; } /***/ }), /***/ "./node_modules/jsonld/lib/flatten.js": /*!********************************************!*\ !*** ./node_modules/jsonld/lib/flatten.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const { isSubjectReference: _isSubjectReference } = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const { createMergedNodeMap: _createMergedNodeMap } = __webpack_require__(/*! ./nodeMap */ "./node_modules/jsonld/lib/nodeMap.js"); const api = {}; module.exports = api; /** * Performs JSON-LD flattening. * * @param input the expanded JSON-LD to flatten. * * @return the flattened output. */ api.flatten = input => { const defaultGraph = _createMergedNodeMap(input); // produce flattened output const flattened = []; const keys = Object.keys(defaultGraph).sort(); for(let ki = 0; ki < keys.length; ++ki) { const node = defaultGraph[keys[ki]]; // only add full subjects to top-level if(!_isSubjectReference(node)) { flattened.push(node); } } return flattened; }; /***/ }), /***/ "./node_modules/jsonld/lib/frame.js": /*!******************************************!*\ !*** ./node_modules/jsonld/lib/frame.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const {isKeyword} = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const graphTypes = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const url = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const { createNodeMap: _createNodeMap, mergeNodeMapGraphs: _mergeNodeMapGraphs } = __webpack_require__(/*! ./nodeMap */ "./node_modules/jsonld/lib/nodeMap.js"); const api = {}; module.exports = api; /** * Performs JSON-LD `merged` framing. * * @param input the expanded JSON-LD to frame. * @param frame the expanded JSON-LD frame to use. * @param options the framing options. * * @return the framed output. */ api.frameMergedOrDefault = (input, frame, options) => { // create framing state const state = { options, embedded: false, graph: '@default', graphMap: {'@default': {}}, subjectStack: [], link: {}, bnodeMap: {} }; // produce a map of all graphs and name each bnode // FIXME: currently uses subjects from @merged graph only const issuer = new util.IdentifierIssuer('_:b'); _createNodeMap(input, state.graphMap, '@default', issuer); if(options.merged) { state.graphMap['@merged'] = _mergeNodeMapGraphs(state.graphMap); state.graph = '@merged'; } state.subjects = state.graphMap[state.graph]; // frame the subjects const framed = []; api.frame(state, Object.keys(state.subjects).sort(), frame, framed); // If pruning blank nodes, find those to prune if(options.pruneBlankNodeIdentifiers) { // remove all blank nodes appearing only once, done in compaction options.bnodesToClear = Object.keys(state.bnodeMap).filter(id => state.bnodeMap[id].length === 1); } // remove @preserve from results options.link = {}; return _cleanupPreserve(framed, options); }; /** * Frames subjects according to the given frame. * * @param state the current framing state. * @param subjects the subjects to filter. * @param frame the frame. * @param parent the parent subject or top-level array. * @param property the parent property, initialized to null. */ api.frame = (state, subjects, frame, parent, property = null) => { // validate the frame _validateFrame(frame); frame = frame[0]; // get flags for current frame const options = state.options; const flags = { embed: _getFrameFlag(frame, options, 'embed'), explicit: _getFrameFlag(frame, options, 'explicit'), requireAll: _getFrameFlag(frame, options, 'requireAll') }; // get link for current graph if(!state.link.hasOwnProperty(state.graph)) { state.link[state.graph] = {}; } const link = state.link[state.graph]; // filter out subjects that match the frame const matches = _filterSubjects(state, subjects, frame, flags); // add matches to output const ids = Object.keys(matches).sort(); for(const id of ids) { const subject = matches[id]; /* Note: In order to treat each top-level match as a compartmentalized result, clear the unique embedded subjects map when the property is null, which only occurs at the top-level. */ if(property === null) { state.uniqueEmbeds = {[state.graph]: {}}; } else { state.uniqueEmbeds[state.graph] = state.uniqueEmbeds[state.graph] || {}; } if(flags.embed === '@link' && id in link) { // TODO: may want to also match an existing linked subject against // the current frame ... so different frames could produce different // subjects that are only shared in-memory when the frames are the same // add existing linked subject _addFrameOutput(parent, property, link[id]); continue; } // start output for subject const output = {'@id': id}; if(id.indexOf('_:') === 0) { util.addValue(state.bnodeMap, id, output, {propertyIsArray: true}); } link[id] = output; // validate @embed if((flags.embed === '@first' || flags.embed === '@last') && state.is11) { throw new JsonLdError( 'Invalid JSON-LD syntax; invalid value of @embed.', 'jsonld.SyntaxError', {code: 'invalid @embed value', frame}); } if(!state.embedded && state.uniqueEmbeds[state.graph].hasOwnProperty(id)) { // skip adding this node object to the top level, as it was // already included in another node object continue; } // if embed is @never or if a circular reference would be created by an // embed, the subject cannot be embedded, just add the reference; // note that a circular reference won't occur when the embed flag is // `@link` as the above check will short-circuit before reaching this point if(state.embedded && (flags.embed === '@never' || _createsCircularReference(subject, state.graph, state.subjectStack))) { _addFrameOutput(parent, property, output); continue; } // if only the first (or once) should be embedded if(state.embedded && (flags.embed == '@first' || flags.embed == '@once') && state.uniqueEmbeds[state.graph].hasOwnProperty(id)) { _addFrameOutput(parent, property, output); continue; } // if only the last match should be embedded if(flags.embed === '@last') { // remove any existing embed if(id in state.uniqueEmbeds[state.graph]) { _removeEmbed(state, id); } } state.uniqueEmbeds[state.graph][id] = {parent, property}; // push matching subject onto stack to enable circular embed checks state.subjectStack.push({subject, graph: state.graph}); // subject is also the name of a graph if(id in state.graphMap) { let recurse = false; let subframe = null; if(!('@graph' in frame)) { recurse = state.graph !== '@merged'; subframe = {}; } else { subframe = frame['@graph'][0]; recurse = !(id === '@merged' || id === '@default'); if(!types.isObject(subframe)) { subframe = {}; } } if(recurse) { // recurse into graph api.frame( {...state, graph: id, embedded: false}, Object.keys(state.graphMap[id]).sort(), [subframe], output, '@graph'); } } // if frame has @included, recurse over its sub-frame if('@included' in frame) { api.frame( {...state, embedded: false}, subjects, frame['@included'], output, '@included'); } // iterate over subject properties for(const prop of Object.keys(subject).sort()) { // copy keywords to output if(isKeyword(prop)) { output[prop] = util.clone(subject[prop]); if(prop === '@type') { // count bnode values of @type for(const type of subject['@type']) { if(type.indexOf('_:') === 0) { util.addValue( state.bnodeMap, type, output, {propertyIsArray: true}); } } } continue; } // explicit is on and property isn't in the frame, skip processing if(flags.explicit && !(prop in frame)) { continue; } // add objects for(const o of subject[prop]) { const subframe = (prop in frame ? frame[prop] : _createImplicitFrame(flags)); // recurse into list if(graphTypes.isList(o)) { const subframe = (frame[prop] && frame[prop][0] && frame[prop][0]['@list']) ? frame[prop][0]['@list'] : _createImplicitFrame(flags); // add empty list const list = {'@list': []}; _addFrameOutput(output, prop, list); // add list objects const src = o['@list']; for(const oo of src) { if(graphTypes.isSubjectReference(oo)) { // recurse into subject reference api.frame( {...state, embedded: true}, [oo['@id']], subframe, list, '@list'); } else { // include other values automatically _addFrameOutput(list, '@list', util.clone(oo)); } } } else if(graphTypes.isSubjectReference(o)) { // recurse into subject reference api.frame( {...state, embedded: true}, [o['@id']], subframe, output, prop); } else if(_valueMatch(subframe[0], o)) { // include other values, if they match _addFrameOutput(output, prop, util.clone(o)); } } } // handle defaults for(const prop of Object.keys(frame).sort()) { // skip keywords if(prop === '@type') { if(!types.isObject(frame[prop][0]) || !('@default' in frame[prop][0])) { continue; } // allow through default types } else if(isKeyword(prop)) { continue; } // if omit default is off, then include default values for properties // that appear in the next frame but are not in the matching subject const next = frame[prop][0] || {}; const omitDefaultOn = _getFrameFlag(next, options, 'omitDefault'); if(!omitDefaultOn && !(prop in output)) { let preserve = '@null'; if('@default' in next) { preserve = util.clone(next['@default']); } if(!types.isArray(preserve)) { preserve = [preserve]; } output[prop] = [{'@preserve': preserve}]; } } // if embed reverse values by finding nodes having this subject as a value // of the associated property for(const reverseProp of Object.keys(frame['@reverse'] || {}).sort()) { const subframe = frame['@reverse'][reverseProp]; for(const subject of Object.keys(state.subjects)) { const nodeValues = util.getValues(state.subjects[subject], reverseProp); if(nodeValues.some(v => v['@id'] === id)) { // node has property referencing this subject, recurse output['@reverse'] = output['@reverse'] || {}; util.addValue( output['@reverse'], reverseProp, [], {propertyIsArray: true}); api.frame( {...state, embedded: true}, [subject], subframe, output['@reverse'][reverseProp], property); } } } // add output to parent _addFrameOutput(parent, property, output); // pop matching subject from circular ref-checking stack state.subjectStack.pop(); } }; /** * Replace `@null` with `null`, removing it from arrays. * * @param input the framed, compacted output. * @param options the framing options used. * * @return the resulting output. */ api.cleanupNull = (input, options) => { // recurse through arrays if(types.isArray(input)) { const noNulls = input.map(v => api.cleanupNull(v, options)); return noNulls.filter(v => v); // removes nulls from array } if(input === '@null') { return null; } if(types.isObject(input)) { // handle in-memory linked nodes if('@id' in input) { const id = input['@id']; if(options.link.hasOwnProperty(id)) { const idx = options.link[id].indexOf(input); if(idx !== -1) { // already visited return options.link[id][idx]; } // prevent circular visitation options.link[id].push(input); } else { // prevent circular visitation options.link[id] = [input]; } } for(const key in input) { input[key] = api.cleanupNull(input[key], options); } } return input; }; /** * Creates an implicit frame when recursing through subject matches. If * a frame doesn't have an explicit frame for a particular property, then * a wildcard child frame will be created that uses the same flags that the * parent frame used. * * @param flags the current framing flags. * * @return the implicit frame. */ function _createImplicitFrame(flags) { const frame = {}; for(const key in flags) { if(flags[key] !== undefined) { frame['@' + key] = [flags[key]]; } } return [frame]; } /** * Checks the current subject stack to see if embedding the given subject * would cause a circular reference. * * @param subjectToEmbed the subject to embed. * @param graph the graph the subject to embed is in. * @param subjectStack the current stack of subjects. * * @return true if a circular reference would be created, false if not. */ function _createsCircularReference(subjectToEmbed, graph, subjectStack) { for(let i = subjectStack.length - 1; i >= 0; --i) { const subject = subjectStack[i]; if(subject.graph === graph && subject.subject['@id'] === subjectToEmbed['@id']) { return true; } } return false; } /** * Gets the frame flag value for the given flag name. * * @param frame the frame. * @param options the framing options. * @param name the flag name. * * @return the flag value. */ function _getFrameFlag(frame, options, name) { const flag = '@' + name; let rval = (flag in frame ? frame[flag][0] : options[name]); if(name === 'embed') { // default is "@last" // backwards-compatibility support for "embed" maps: // true => "@last" // false => "@never" if(rval === true) { rval = '@once'; } else if(rval === false) { rval = '@never'; } else if(rval !== '@always' && rval !== '@never' && rval !== '@link' && rval !== '@first' && rval !== '@last' && rval !== '@once') { throw new JsonLdError( 'Invalid JSON-LD syntax; invalid value of @embed.', 'jsonld.SyntaxError', {code: 'invalid @embed value', frame}); } } return rval; } /** * Validates a JSON-LD frame, throwing an exception if the frame is invalid. * * @param frame the frame to validate. */ function _validateFrame(frame) { if(!types.isArray(frame) || frame.length !== 1 || !types.isObject(frame[0])) { throw new JsonLdError( 'Invalid JSON-LD syntax; a JSON-LD frame must be a single object.', 'jsonld.SyntaxError', {frame}); } if('@id' in frame[0]) { for(const id of util.asArray(frame[0]['@id'])) { // @id must be wildcard or an IRI if(!(types.isObject(id) || url.isAbsolute(id)) || (types.isString(id) && id.indexOf('_:') === 0)) { throw new JsonLdError( 'Invalid JSON-LD syntax; invalid @id in frame.', 'jsonld.SyntaxError', {code: 'invalid frame', frame}); } } } if('@type' in frame[0]) { for(const type of util.asArray(frame[0]['@type'])) { // @id must be wildcard or an IRI if(!(types.isObject(type) || url.isAbsolute(type)) || (types.isString(type) && type.indexOf('_:') === 0)) { throw new JsonLdError( 'Invalid JSON-LD syntax; invalid @type in frame.', 'jsonld.SyntaxError', {code: 'invalid frame', frame}); } } } } /** * Returns a map of all of the subjects that match a parsed frame. * * @param state the current framing state. * @param subjects the set of subjects to filter. * @param frame the parsed frame. * @param flags the frame flags. * * @return all of the matched subjects. */ function _filterSubjects(state, subjects, frame, flags) { // filter subjects in @id order const rval = {}; for(const id of subjects) { const subject = state.graphMap[state.graph][id]; if(_filterSubject(state, subject, frame, flags)) { rval[id] = subject; } } return rval; } /** * Returns true if the given subject matches the given frame. * * Matches either based on explicit type inclusion where the node has any * type listed in the frame. If the frame has empty types defined matches * nodes not having a @type. If the frame has a type of {} defined matches * nodes having any type defined. * * Otherwise, does duck typing, where the node must have all of the * properties defined in the frame. * * @param state the current framing state. * @param subject the subject to check. * @param frame the frame to check. * @param flags the frame flags. * * @return true if the subject matches, false if not. */ function _filterSubject(state, subject, frame, flags) { // check ducktype let wildcard = true; let matchesSome = false; for(const key in frame) { let matchThis = false; const nodeValues = util.getValues(subject, key); const isEmpty = util.getValues(frame, key).length === 0; if(key === '@id') { // match on no @id or any matching @id, including wildcard if(types.isEmptyObject(frame['@id'][0] || {})) { matchThis = true; } else if(frame['@id'].length >= 0) { matchThis = frame['@id'].includes(nodeValues[0]); } if(!flags.requireAll) { return matchThis; } } else if(key === '@type') { // check @type (object value means 'any' type, // fall through to ducktyping) wildcard = false; if(isEmpty) { if(nodeValues.length > 0) { // don't match on no @type return false; } matchThis = true; } else if(frame['@type'].length === 1 && types.isEmptyObject(frame['@type'][0])) { // match on wildcard @type if there is a type matchThis = nodeValues.length > 0; } else { // match on a specific @type for(const type of frame['@type']) { if(types.isObject(type) && '@default' in type) { // match on default object matchThis = true; } else { matchThis = matchThis || nodeValues.some(tt => tt === type); } } } if(!flags.requireAll) { return matchThis; } } else if(isKeyword(key)) { continue; } else { // Force a copy of this frame entry so it can be manipulated const thisFrame = util.getValues(frame, key)[0]; let hasDefault = false; if(thisFrame) { _validateFrame([thisFrame]); hasDefault = '@default' in thisFrame; } // no longer a wildcard pattern if frame has any non-keyword properties wildcard = false; // skip, but allow match if node has no value for property, and frame has // a default value if(nodeValues.length === 0 && hasDefault) { continue; } // if frame value is empty, don't match if subject has any value if(nodeValues.length > 0 && isEmpty) { return false; } if(thisFrame === undefined) { // node does not match if values is not empty and the value of property // in frame is match none. if(nodeValues.length > 0) { return false; } matchThis = true; } else { if(graphTypes.isList(thisFrame)) { const listValue = thisFrame['@list'][0]; if(graphTypes.isList(nodeValues[0])) { const nodeListValues = nodeValues[0]['@list']; if(graphTypes.isValue(listValue)) { // match on any matching value matchThis = nodeListValues.some(lv => _valueMatch(listValue, lv)); } else if(graphTypes.isSubject(listValue) || graphTypes.isSubjectReference(listValue)) { matchThis = nodeListValues.some(lv => _nodeMatch( state, listValue, lv, flags)); } } } else if(graphTypes.isValue(thisFrame)) { matchThis = nodeValues.some(nv => _valueMatch(thisFrame, nv)); } else if(graphTypes.isSubjectReference(thisFrame)) { matchThis = nodeValues.some(nv => _nodeMatch(state, thisFrame, nv, flags)); } else if(types.isObject(thisFrame)) { matchThis = nodeValues.length > 0; } else { matchThis = false; } } } // all non-defaulted values must match if requireAll is set if(!matchThis && flags.requireAll) { return false; } matchesSome = matchesSome || matchThis; } // return true if wildcard or subject matches some properties return wildcard || matchesSome; } /** * Removes an existing embed. * * @param state the current framing state. * @param id the @id of the embed to remove. */ function _removeEmbed(state, id) { // get existing embed const embeds = state.uniqueEmbeds[state.graph]; const embed = embeds[id]; const parent = embed.parent; const property = embed.property; // create reference to replace embed const subject = {'@id': id}; // remove existing embed if(types.isArray(parent)) { // replace subject with reference for(let i = 0; i < parent.length; ++i) { if(util.compareValues(parent[i], subject)) { parent[i] = subject; break; } } } else { // replace subject with reference const useArray = types.isArray(parent[property]); util.removeValue(parent, property, subject, {propertyIsArray: useArray}); util.addValue(parent, property, subject, {propertyIsArray: useArray}); } // recursively remove dependent dangling embeds const removeDependents = id => { // get embed keys as a separate array to enable deleting keys in map const ids = Object.keys(embeds); for(const next of ids) { if(next in embeds && types.isObject(embeds[next].parent) && embeds[next].parent['@id'] === id) { delete embeds[next]; removeDependents(next); } } }; removeDependents(id); } /** * Removes the @preserve keywords from expanded result of framing. * * @param input the framed, framed output. * @param options the framing options used. * * @return the resulting output. */ function _cleanupPreserve(input, options) { // recurse through arrays if(types.isArray(input)) { return input.map(value => _cleanupPreserve(value, options)); } if(types.isObject(input)) { // remove @preserve if('@preserve' in input) { return input['@preserve'][0]; } // skip @values if(graphTypes.isValue(input)) { return input; } // recurse through @lists if(graphTypes.isList(input)) { input['@list'] = _cleanupPreserve(input['@list'], options); return input; } // handle in-memory linked nodes if('@id' in input) { const id = input['@id']; if(options.link.hasOwnProperty(id)) { const idx = options.link[id].indexOf(input); if(idx !== -1) { // already visited return options.link[id][idx]; } // prevent circular visitation options.link[id].push(input); } else { // prevent circular visitation options.link[id] = [input]; } } // recurse through properties for(const prop in input) { // potentially remove the id, if it is an unreference bnode if(prop === '@id' && options.bnodesToClear.includes(input[prop])) { delete input['@id']; continue; } input[prop] = _cleanupPreserve(input[prop], options); } } return input; } /** * Adds framing output to the given parent. * * @param parent the parent to add to. * @param property the parent property. * @param output the output to add. */ function _addFrameOutput(parent, property, output) { if(types.isObject(parent)) { util.addValue(parent, property, output, {propertyIsArray: true}); } else { parent.push(output); } } /** * Node matches if it is a node, and matches the pattern as a frame. * * @param state the current framing state. * @param pattern used to match value * @param value to check * @param flags the frame flags. */ function _nodeMatch(state, pattern, value, flags) { if(!('@id' in value)) { return false; } const nodeObject = state.subjects[value['@id']]; return nodeObject && _filterSubject(state, nodeObject, pattern, flags); } /** * Value matches if it is a value and matches the value pattern * * * `pattern` is empty * * @values are the same, or `pattern[@value]` is a wildcard, and * * @types are the same or `value[@type]` is not null * and `pattern[@type]` is `{}`, or `value[@type]` is null * and `pattern[@type]` is null or `[]`, and * * @languages are the same or `value[@language]` is not null * and `pattern[@language]` is `{}`, or `value[@language]` is null * and `pattern[@language]` is null or `[]`. * * @param pattern used to match value * @param value to check */ function _valueMatch(pattern, value) { const v1 = value['@value']; const t1 = value['@type']; const l1 = value['@language']; const v2 = pattern['@value'] ? (types.isArray(pattern['@value']) ? pattern['@value'] : [pattern['@value']]) : []; const t2 = pattern['@type'] ? (types.isArray(pattern['@type']) ? pattern['@type'] : [pattern['@type']]) : []; const l2 = pattern['@language'] ? (types.isArray(pattern['@language']) ? pattern['@language'] : [pattern['@language']]) : []; if(v2.length === 0 && t2.length === 0 && l2.length === 0) { return true; } if(!(v2.includes(v1) || types.isEmptyObject(v2[0]))) { return false; } if(!(!t1 && t2.length === 0 || t2.includes(t1) || t1 && types.isEmptyObject(t2[0]))) { return false; } if(!(!l1 && l2.length === 0 || l2.includes(l1) || l1 && types.isEmptyObject(l2[0]))) { return false; } return true; } /***/ }), /***/ "./node_modules/jsonld/lib/fromRdf.js": /*!********************************************!*\ !*** ./node_modules/jsonld/lib/fromRdf.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const graphTypes = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); // constants const { // RDF, RDF_LIST, RDF_FIRST, RDF_REST, RDF_NIL, RDF_TYPE, // RDF_PLAIN_LITERAL, // RDF_XML_LITERAL, RDF_JSON_LITERAL, // RDF_OBJECT, // RDF_LANGSTRING, // XSD, XSD_BOOLEAN, XSD_DOUBLE, XSD_INTEGER, XSD_STRING, } = __webpack_require__(/*! ./constants */ "./node_modules/jsonld/lib/constants.js"); const REGEX_BCP47 = /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/; const api = {}; module.exports = api; /** * Converts an RDF dataset to JSON-LD. * * @param dataset the RDF dataset. * @param options the RDF serialization options. * * @return a Promise that resolves to the JSON-LD output. */ api.fromRDF = async ( dataset, { useRdfType = false, useNativeTypes = false, rdfDirection = null } ) => { const defaultGraph = {}; const graphMap = {'@default': defaultGraph}; const referencedOnce = {}; for(const quad of dataset) { // TODO: change 'name' to 'graph' const name = (quad.graph.termType === 'DefaultGraph') ? '@default' : quad.graph.value; if(!(name in graphMap)) { graphMap[name] = {}; } if(name !== '@default' && !(name in defaultGraph)) { defaultGraph[name] = {'@id': name}; } const nodeMap = graphMap[name]; // get subject, predicate, object const s = quad.subject.value; const p = quad.predicate.value; const o = quad.object; if(!(s in nodeMap)) { nodeMap[s] = {'@id': s}; } const node = nodeMap[s]; const objectIsNode = o.termType.endsWith('Node'); if(objectIsNode && !(o.value in nodeMap)) { nodeMap[o.value] = {'@id': o.value}; } if(p === RDF_TYPE && !useRdfType && objectIsNode) { util.addValue(node, '@type', o.value, {propertyIsArray: true}); continue; } const value = _RDFToObject(o, useNativeTypes, rdfDirection); util.addValue(node, p, value, {propertyIsArray: true}); // object may be an RDF list/partial list node but we can't know easily // until all triples are read if(objectIsNode) { if(o.value === RDF_NIL) { // track rdf:nil uniquely per graph const object = nodeMap[o.value]; if(!('usages' in object)) { object.usages = []; } object.usages.push({ node, property: p, value }); } else if(o.value in referencedOnce) { // object referenced more than once referencedOnce[o.value] = false; } else { // keep track of single reference referencedOnce[o.value] = { node, property: p, value }; } } } /* for(let name in dataset) { const graph = dataset[name]; if(!(name in graphMap)) { graphMap[name] = {}; } if(name !== '@default' && !(name in defaultGraph)) { defaultGraph[name] = {'@id': name}; } const nodeMap = graphMap[name]; for(let ti = 0; ti < graph.length; ++ti) { const triple = graph[ti]; // get subject, predicate, object const s = triple.subject.value; const p = triple.predicate.value; const o = triple.object; if(!(s in nodeMap)) { nodeMap[s] = {'@id': s}; } const node = nodeMap[s]; const objectIsId = (o.type === 'IRI' || o.type === 'blank node'); if(objectIsId && !(o.value in nodeMap)) { nodeMap[o.value] = {'@id': o.value}; } if(p === RDF_TYPE && !useRdfType && objectIsId) { util.addValue(node, '@type', o.value, {propertyIsArray: true}); continue; } const value = _RDFToObject(o, useNativeTypes); util.addValue(node, p, value, {propertyIsArray: true}); // object may be an RDF list/partial list node but we can't know easily // until all triples are read if(objectIsId) { if(o.value === RDF_NIL) { // track rdf:nil uniquely per graph const object = nodeMap[o.value]; if(!('usages' in object)) { object.usages = []; } object.usages.push({ node: node, property: p, value: value }); } else if(o.value in referencedOnce) { // object referenced more than once referencedOnce[o.value] = false; } else { // keep track of single reference referencedOnce[o.value] = { node: node, property: p, value: value }; } } } }*/ // convert linked lists to @list arrays for(const name in graphMap) { const graphObject = graphMap[name]; // no @lists to be converted, continue if(!(RDF_NIL in graphObject)) { continue; } // iterate backwards through each RDF list const nil = graphObject[RDF_NIL]; if(!nil.usages) { continue; } for(let usage of nil.usages) { let node = usage.node; let property = usage.property; let head = usage.value; const list = []; const listNodes = []; // ensure node is a well-formed list node; it must: // 1. Be referenced only once. // 2. Have an array for rdf:first that has 1 item. // 3. Have an array for rdf:rest that has 1 item. // 4. Have no keys other than: @id, rdf:first, rdf:rest, and, // optionally, @type where the value is rdf:List. let nodeKeyCount = Object.keys(node).length; while(property === RDF_REST && types.isObject(referencedOnce[node['@id']]) && types.isArray(node[RDF_FIRST]) && node[RDF_FIRST].length === 1 && types.isArray(node[RDF_REST]) && node[RDF_REST].length === 1 && (nodeKeyCount === 3 || (nodeKeyCount === 4 && types.isArray(node['@type']) && node['@type'].length === 1 && node['@type'][0] === RDF_LIST))) { list.push(node[RDF_FIRST][0]); listNodes.push(node['@id']); // get next node, moving backwards through list usage = referencedOnce[node['@id']]; node = usage.node; property = usage.property; head = usage.value; nodeKeyCount = Object.keys(node).length; // if node is not a blank node, then list head found if(!graphTypes.isBlankNode(node)) { break; } } // transform list into @list object delete head['@id']; head['@list'] = list.reverse(); for(const listNode of listNodes) { delete graphObject[listNode]; } } delete nil.usages; } const result = []; const subjects = Object.keys(defaultGraph).sort(); for(const subject of subjects) { const node = defaultGraph[subject]; if(subject in graphMap) { const graph = node['@graph'] = []; const graphObject = graphMap[subject]; const graphSubjects = Object.keys(graphObject).sort(); for(const graphSubject of graphSubjects) { const node = graphObject[graphSubject]; // only add full subjects to top-level if(!graphTypes.isSubjectReference(node)) { graph.push(node); } } } // only add full subjects to top-level if(!graphTypes.isSubjectReference(node)) { result.push(node); } } return result; }; /** * Converts an RDF triple object to a JSON-LD object. * * @param o the RDF triple object to convert. * @param useNativeTypes true to output native types, false not to. * * @return the JSON-LD object. */ function _RDFToObject(o, useNativeTypes, rdfDirection) { // convert NamedNode/BlankNode object to JSON-LD if(o.termType.endsWith('Node')) { return {'@id': o.value}; } // convert literal to JSON-LD const rval = {'@value': o.value}; // add language if(o.language) { rval['@language'] = o.language; } else { let type = o.datatype.value; if(!type) { type = XSD_STRING; } if(type === RDF_JSON_LITERAL) { type = '@json'; try { rval['@value'] = JSON.parse(rval['@value']); } catch(e) { throw new JsonLdError( 'JSON literal could not be parsed.', 'jsonld.InvalidJsonLiteral', {code: 'invalid JSON literal', value: rval['@value'], cause: e}); } } // use native types for certain xsd types if(useNativeTypes) { if(type === XSD_BOOLEAN) { if(rval['@value'] === 'true') { rval['@value'] = true; } else if(rval['@value'] === 'false') { rval['@value'] = false; } } else if(types.isNumeric(rval['@value'])) { if(type === XSD_INTEGER) { const i = parseInt(rval['@value'], 10); if(i.toFixed(0) === rval['@value']) { rval['@value'] = i; } } else if(type === XSD_DOUBLE) { rval['@value'] = parseFloat(rval['@value']); } } // do not add native type if(![XSD_BOOLEAN, XSD_INTEGER, XSD_DOUBLE, XSD_STRING].includes(type)) { rval['@type'] = type; } } else if(rdfDirection === 'i18n-datatype' && type.startsWith('https://www.w3.org/ns/i18n#')) { const [, language, direction] = type.split(/[#_]/); if(language.length > 0) { rval['@language'] = language; if(!language.match(REGEX_BCP47)) { console.warn(`@language must be valid BCP47: ${language}`); } } rval['@direction'] = direction; } else if(type !== XSD_STRING) { rval['@type'] = type; } } return rval; } /***/ }), /***/ "./node_modules/jsonld/lib/graphTypes.js": /*!***********************************************!*\ !*** ./node_modules/jsonld/lib/graphTypes.js ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const api = {}; module.exports = api; /** * Returns true if the given value is a subject with properties. * * @param v the value to check. * * @return true if the value is a subject with properties, false if not. */ api.isSubject = v => { // Note: A value is a subject if all of these hold true: // 1. It is an Object. // 2. It is not a @value, @set, or @list. // 3. It has more than 1 key OR any existing key is not @id. if(types.isObject(v) && !(('@value' in v) || ('@set' in v) || ('@list' in v))) { const keyCount = Object.keys(v).length; return (keyCount > 1 || !('@id' in v)); } return false; }; /** * Returns true if the given value is a subject reference. * * @param v the value to check. * * @return true if the value is a subject reference, false if not. */ api.isSubjectReference = v => // Note: A value is a subject reference if all of these hold true: // 1. It is an Object. // 2. It has a single key: @id. (types.isObject(v) && Object.keys(v).length === 1 && ('@id' in v)); /** * Returns true if the given value is a @value. * * @param v the value to check. * * @return true if the value is a @value, false if not. */ api.isValue = v => // Note: A value is a @value if all of these hold true: // 1. It is an Object. // 2. It has the @value property. types.isObject(v) && ('@value' in v); /** * Returns true if the given value is a @list. * * @param v the value to check. * * @return true if the value is a @list, false if not. */ api.isList = v => // Note: A value is a @list if all of these hold true: // 1. It is an Object. // 2. It has the @list property. types.isObject(v) && ('@list' in v); /** * Returns true if the given value is a @graph. * * @return true if the value is a @graph, false if not. */ api.isGraph = v => { // Note: A value is a graph if all of these hold true: // 1. It is an object. // 2. It has an `@graph` key. // 3. It may have '@id' or '@index' return types.isObject(v) && '@graph' in v && Object.keys(v) .filter(key => key !== '@id' && key !== '@index').length === 1; }; /** * Returns true if the given value is a simple @graph. * * @return true if the value is a simple @graph, false if not. */ api.isSimpleGraph = v => { // Note: A value is a simple graph if all of these hold true: // 1. It is an object. // 2. It has an `@graph` key. // 3. It has only 1 key or 2 keys where one of them is `@index`. return api.isGraph(v) && !('@id' in v); }; /** * Returns true if the given value is a blank node. * * @param v the value to check. * * @return true if the value is a blank node, false if not. */ api.isBlankNode = v => { // Note: A value is a blank node if all of these hold true: // 1. It is an Object. // 2. If it has an @id key its value begins with '_:'. // 3. It has no keys OR is not a @value, @set, or @list. if(types.isObject(v)) { if('@id' in v) { return (v['@id'].indexOf('_:') === 0); } return (Object.keys(v).length === 0 || !(('@value' in v) || ('@set' in v) || ('@list' in v))); } return false; }; /***/ }), /***/ "./node_modules/jsonld/lib/jsonld.js": /*!*******************************************!*\ !*** ./node_modules/jsonld/lib/jsonld.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process, global) {/** * A JavaScript implementation of the JSON-LD API. * * @author Dave Longley * * @license BSD 3-Clause License * Copyright (c) 2011-2019 Digital Bazaar, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Digital Bazaar, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ const canonize = __webpack_require__(/*! rdf-canonize */ "./node_modules/rdf-canonize/lib/index.js"); const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const ContextResolver = __webpack_require__(/*! ./ContextResolver */ "./node_modules/jsonld/lib/ContextResolver.js"); const IdentifierIssuer = util.IdentifierIssuer; const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/lru-cache/index.js"); const NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/jsonld/lib/NQuads.js"); const Rdfa = __webpack_require__(/*! ./Rdfa */ "./node_modules/jsonld/lib/Rdfa.js"); const {expand: _expand} = __webpack_require__(/*! ./expand */ "./node_modules/jsonld/lib/expand.js"); const {flatten: _flatten} = __webpack_require__(/*! ./flatten */ "./node_modules/jsonld/lib/flatten.js"); const {fromRDF: _fromRDF} = __webpack_require__(/*! ./fromRdf */ "./node_modules/jsonld/lib/fromRdf.js"); const {toRDF: _toRDF} = __webpack_require__(/*! ./toRdf */ "./node_modules/jsonld/lib/toRdf.js"); const { frameMergedOrDefault: _frameMergedOrDefault, cleanupNull: _cleanupNull } = __webpack_require__(/*! ./frame */ "./node_modules/jsonld/lib/frame.js"); const { isArray: _isArray, isObject: _isObject, isString: _isString } = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const { isSubjectReference: _isSubjectReference, } = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const { expandIri: _expandIri, getInitialContext: _getInitialContext, process: _processContext, processingMode: _processingMode } = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const { compact: _compact, compactIri: _compactIri } = __webpack_require__(/*! ./compact */ "./node_modules/jsonld/lib/compact.js"); const { createNodeMap: _createNodeMap, createMergedNodeMap: _createMergedNodeMap, mergeNodeMaps: _mergeNodeMaps } = __webpack_require__(/*! ./nodeMap */ "./node_modules/jsonld/lib/nodeMap.js"); // determine if in-browser or using Node.js const _nodejs = ( typeof process !== 'undefined' && process.versions && process.versions.node); const _browser = !_nodejs && (typeof window !== 'undefined' || typeof self !== 'undefined'); /* eslint-disable indent */ // attaches jsonld API to the given object const wrapper = function(jsonld) { /** Registered RDF dataset parsers hashed by content-type. */ const _rdfParsers = {}; // resolved context cache // TODO: consider basing max on context size rather than number const RESOLVED_CONTEXT_CACHE_MAX_SIZE = 100; const _resolvedContextCache = new LRU({max: RESOLVED_CONTEXT_CACHE_MAX_SIZE}); /* Core API */ /** * Performs JSON-LD compaction. * * @param input the JSON-LD input to compact. * @param ctx the context to compact with. * @param [options] options to use: * [base] the base IRI to use. * [compactArrays] true to compact arrays to single values when * appropriate, false not to (default: true). * [compactToRelative] true to compact IRIs to be relative to document * base, false to keep absolute (default: true) * [graph] true to always output a top-level graph (default: false). * [expandContext] a context to expand with. * [skipExpansion] true to assume the input is expanded and skip * expansion, false not to, defaults to false. * [documentLoader(url, options)] the document loader. * [expansionMap(info)] a function that can be used to custom map * unmappable values (or to throw an error when they are detected); * if this function returns `undefined` then the default behavior * will be used. * [framing] true if compaction is occuring during a framing operation. * [compactionMap(info)] a function that can be used to custom map * unmappable values (or to throw an error when they are detected); * if this function returns `undefined` then the default behavior * will be used. * [contextResolver] internal use only. * * @return a Promise that resolves to the compacted output. */ jsonld.compact = async function(input, ctx, options) { if(arguments.length < 2) { throw new TypeError('Could not compact, too few arguments.'); } if(ctx === null) { throw new JsonLdError( 'The compaction context must not be null.', 'jsonld.CompactError', {code: 'invalid local context'}); } // nothing to compact if(input === null) { return null; } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', compactArrays: true, compactToRelative: true, graph: false, skipExpansion: false, link: false, issuer: new IdentifierIssuer('_:b'), contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); if(options.link) { // force skip expansion when linking, "link" is not part of the public // API, it should only be called from framing options.skipExpansion = true; } if(!options.compactToRelative) { delete options.base; } // expand input let expanded; if(options.skipExpansion) { expanded = input; } else { expanded = await jsonld.expand(input, options); } // process context const activeCtx = await jsonld.processContext( _getInitialContext(options), ctx, options); // do compaction let compacted = await _compact({ activeCtx, element: expanded, options, compactionMap: options.compactionMap }); // perform clean up if(options.compactArrays && !options.graph && _isArray(compacted)) { if(compacted.length === 1) { // simplify to a single item compacted = compacted[0]; } else if(compacted.length === 0) { // simplify to an empty object compacted = {}; } } else if(options.graph && _isObject(compacted)) { // always use array if graph option is on compacted = [compacted]; } // follow @context key if(_isObject(ctx) && '@context' in ctx) { ctx = ctx['@context']; } // build output context ctx = util.clone(ctx); if(!_isArray(ctx)) { ctx = [ctx]; } // remove empty contexts const tmp = ctx; ctx = []; for(let i = 0; i < tmp.length; ++i) { if(!_isObject(tmp[i]) || Object.keys(tmp[i]).length > 0) { ctx.push(tmp[i]); } } // remove array if only one context const hasContext = (ctx.length > 0); if(ctx.length === 1) { ctx = ctx[0]; } // add context and/or @graph if(_isArray(compacted)) { // use '@graph' keyword const graphAlias = _compactIri({ activeCtx, iri: '@graph', relativeTo: {vocab: true} }); const graph = compacted; compacted = {}; if(hasContext) { compacted['@context'] = ctx; } compacted[graphAlias] = graph; } else if(_isObject(compacted) && hasContext) { // reorder keys so @context is first const graph = compacted; compacted = {'@context': ctx}; for(const key in graph) { compacted[key] = graph[key]; } } return compacted; }; /** * Performs JSON-LD expansion. * * @param input the JSON-LD input to expand. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [keepFreeFloatingNodes] true to keep free-floating nodes, * false not to, defaults to false. * [documentLoader(url, options)] the document loader. * [expansionMap(info)] a function that can be used to custom map * unmappable values (or to throw an error when they are detected); * if this function returns `undefined` then the default behavior * will be used. * [contextResolver] internal use only. * * @return a Promise that resolves to the expanded output. */ jsonld.expand = async function(input, options) { if(arguments.length < 1) { throw new TypeError('Could not expand, too few arguments.'); } // set default options options = _setDefaults(options, { keepFreeFloatingNodes: false, contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); if(options.expansionMap === false) { options.expansionMap = undefined; } // build set of objects that may have @contexts to resolve const toResolve = {}; // build set of contexts to process prior to expansion const contextsToProcess = []; // if an `expandContext` has been given ensure it gets resolved if('expandContext' in options) { const expandContext = util.clone(options.expandContext); if(_isObject(expandContext) && '@context' in expandContext) { toResolve.expandContext = expandContext; } else { toResolve.expandContext = {'@context': expandContext}; } contextsToProcess.push(toResolve.expandContext); } // if input is a string, attempt to dereference remote document let defaultBase; if(!_isString(input)) { // input is not a URL, do not need to retrieve it first toResolve.input = util.clone(input); } else { // load remote doc const remoteDoc = await jsonld.get(input, options); defaultBase = remoteDoc.documentUrl; toResolve.input = remoteDoc.document; if(remoteDoc.contextUrl) { // context included in HTTP link header and must be resolved toResolve.remoteContext = {'@context': remoteDoc.contextUrl}; contextsToProcess.push(toResolve.remoteContext); } } // set default base if(!('base' in options)) { options.base = defaultBase || ''; } // process any additional contexts let activeCtx = _getInitialContext(options); for(const localCtx of contextsToProcess) { activeCtx = await _processContext({activeCtx, localCtx, options}); } // expand resolved input let expanded = await _expand({ activeCtx, element: toResolve.input, options, expansionMap: options.expansionMap }); // optimize away @graph with no other properties if(_isObject(expanded) && ('@graph' in expanded) && Object.keys(expanded).length === 1) { expanded = expanded['@graph']; } else if(expanded === null) { expanded = []; } // normalize to an array if(!_isArray(expanded)) { expanded = [expanded]; } return expanded; }; /** * Performs JSON-LD flattening. * * @param input the JSON-LD to flatten. * @param ctx the context to use to compact the flattened output, or null. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the flattened output. */ jsonld.flatten = async function(input, ctx, options) { if(arguments.length < 1) { return new TypeError('Could not flatten, too few arguments.'); } if(typeof ctx === 'function') { ctx = null; } else { ctx = ctx || null; } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // expand input const expanded = await jsonld.expand(input, options); // do flattening const flattened = _flatten(expanded); if(ctx === null) { // no compaction required return flattened; } // compact result (force @graph option to true, skip expansion) options.graph = true; options.skipExpansion = true; const compacted = await jsonld.compact(flattened, ctx, options); return compacted; }; /** * Performs JSON-LD framing. * * @param input the JSON-LD input to frame. * @param frame the JSON-LD frame to use. * @param [options] the framing options. * [base] the base IRI to use. * [expandContext] a context to expand with. * [embed] default @embed flag: '@last', '@always', '@never', '@link' * (default: '@last'). * [explicit] default @explicit flag (default: false). * [requireAll] default @requireAll flag (default: true). * [omitDefault] default @omitDefault flag (default: false). * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the framed output. */ jsonld.frame = async function(input, frame, options) { if(arguments.length < 2) { throw new TypeError('Could not frame, too few arguments.'); } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', embed: '@once', explicit: false, requireAll: false, omitDefault: false, bnodesToClear: [], contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // if frame is a string, attempt to dereference remote document if(_isString(frame)) { // load remote doc const remoteDoc = await jsonld.get(frame, options); frame = remoteDoc.document; if(remoteDoc.contextUrl) { // inject link header @context into frame let ctx = frame['@context']; if(!ctx) { ctx = remoteDoc.contextUrl; } else if(_isArray(ctx)) { ctx.push(remoteDoc.contextUrl); } else { ctx = [ctx, remoteDoc.contextUrl]; } frame['@context'] = ctx; } } const frameContext = frame ? frame['@context'] || {} : {}; // process context const activeCtx = await jsonld.processContext( _getInitialContext(options), frameContext, options); // mode specific defaults if(!options.hasOwnProperty('omitGraph')) { options.omitGraph = _processingMode(activeCtx, 1.1); } if(!options.hasOwnProperty('pruneBlankNodeIdentifiers')) { options.pruneBlankNodeIdentifiers = _processingMode(activeCtx, 1.1); } // expand input const expanded = await jsonld.expand(input, options); // expand frame const opts = {...options}; opts.isFrame = true; opts.keepFreeFloatingNodes = true; const expandedFrame = await jsonld.expand(frame, opts); // if the unexpanded frame includes a key expanding to @graph, frame the // default graph, otherwise, the merged graph const frameKeys = Object.keys(frame) .map(key => _expandIri(activeCtx, key, {vocab: true})); opts.merged = !frameKeys.includes('@graph'); opts.is11 = _processingMode(activeCtx, 1.1); // do framing const framed = _frameMergedOrDefault(expanded, expandedFrame, opts); opts.graph = !options.omitGraph; opts.skipExpansion = true; opts.link = {}; opts.framing = true; let compacted = await jsonld.compact(framed, frameContext, opts); // replace @null with null, compacting arrays opts.link = {}; compacted = _cleanupNull(compacted, opts); return compacted; }; /** * **Experimental** * * Links a JSON-LD document's nodes in memory. * * @param input the JSON-LD document to link. * @param [ctx] the JSON-LD context to apply. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the linked output. */ jsonld.link = async function(input, ctx, options) { // API matches running frame with a wildcard frame and embed: '@link' // get arguments const frame = {}; if(ctx) { frame['@context'] = ctx; } frame['@embed'] = '@link'; return jsonld.frame(input, frame, options); }; /** * Performs RDF dataset normalization on the given input. The input is JSON-LD * unless the 'inputFormat' option is used. The output is an RDF dataset * unless the 'format' option is used. * * @param input the input to normalize as JSON-LD or as a format specified by * the 'inputFormat' option. * @param [options] the options to use: * [algorithm] the normalization algorithm to use, `URDNA2015` or * `URGNA2012` (default: `URDNA2015`). * [base] the base IRI to use. * [expandContext] a context to expand with. * [skipExpansion] true to assume the input is expanded and skip * expansion, false not to, defaults to false. * [inputFormat] the format if input is not JSON-LD: * 'application/n-quads' for N-Quads. * [format] the format if output is a string: * 'application/n-quads' for N-Quads. * [documentLoader(url, options)] the document loader. * [useNative] true to use a native canonize algorithm * [contextResolver] internal use only. * * @return a Promise that resolves to the normalized output. */ jsonld.normalize = jsonld.canonize = async function(input, options) { if(arguments.length < 1) { throw new TypeError('Could not canonize, too few arguments.'); } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', algorithm: 'URDNA2015', skipExpansion: false, contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); if('inputFormat' in options) { if(options.inputFormat !== 'application/n-quads' && options.inputFormat !== 'application/nquads') { throw new JsonLdError( 'Unknown canonicalization input format.', 'jsonld.CanonizeError'); } // TODO: `await` for async parsers const parsedInput = NQuads.parse(input); // do canonicalization return canonize.canonize(parsedInput, options); } // convert to RDF dataset then do normalization const opts = {...options}; delete opts.format; opts.produceGeneralizedRdf = false; const dataset = await jsonld.toRDF(input, opts); // do canonicalization return canonize.canonize(dataset, options); }; /** * Converts an RDF dataset to JSON-LD. * * @param dataset a serialized string of RDF in a format specified by the * format option or an RDF dataset to convert. * @param [options] the options to use: * [format] the format if dataset param must first be parsed: * 'application/n-quads' for N-Quads (default). * [rdfParser] a custom RDF-parser to use to parse the dataset. * [useRdfType] true to use rdf:type, false to use @type * (default: false). * [useNativeTypes] true to convert XSD types into native types * (boolean, integer, double), false not to (default: false). * * @return a Promise that resolves to the JSON-LD document. */ jsonld.fromRDF = async function(dataset, options) { if(arguments.length < 1) { throw new TypeError('Could not convert from RDF, too few arguments.'); } // set default options options = _setDefaults(options, { format: _isString(dataset) ? 'application/n-quads' : undefined }); const {format} = options; let {rdfParser} = options; // handle special format if(format) { // check supported formats rdfParser = rdfParser || _rdfParsers[format]; if(!rdfParser) { throw new JsonLdError( 'Unknown input format.', 'jsonld.UnknownFormat', {format}); } } else { // no-op parser, assume dataset already parsed rdfParser = () => dataset; } // rdfParser must be synchronous or return a promise, no callback support const parsedDataset = await rdfParser(dataset); return _fromRDF(parsedDataset, options); }; /** * Outputs the RDF dataset found in the given JSON-LD object. * * @param input the JSON-LD input. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [skipExpansion] true to assume the input is expanded and skip * expansion, false not to, defaults to false. * [format] the format to use to output a string: * 'application/n-quads' for N-Quads. * [produceGeneralizedRdf] true to output generalized RDF, false * to produce only standard RDF (default: false). * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the RDF dataset. */ jsonld.toRDF = async function(input, options) { if(arguments.length < 1) { throw new TypeError('Could not convert to RDF, too few arguments.'); } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', skipExpansion: false, contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // TODO: support toRDF custom map? let expanded; if(options.skipExpansion) { expanded = input; } else { // expand input expanded = await jsonld.expand(input, options); } // output RDF dataset const dataset = _toRDF(expanded, options); if(options.format) { if(options.format === 'application/n-quads' || options.format === 'application/nquads') { return await NQuads.serialize(dataset); } throw new JsonLdError( 'Unknown output format.', 'jsonld.UnknownFormat', {format: options.format}); } return dataset; }; /** * **Experimental** * * Recursively flattens the nodes in the given JSON-LD input into a merged * map of node ID => node. All graphs will be merged into the default graph. * * @param input the JSON-LD input. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [issuer] a jsonld.IdentifierIssuer to use to label blank nodes. * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the merged node map. */ jsonld.createNodeMap = async function(input, options) { if(arguments.length < 1) { throw new TypeError('Could not create node map, too few arguments.'); } // set default options options = _setDefaults(options, { base: _isString(input) ? input : '', contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // expand input const expanded = await jsonld.expand(input, options); return _createMergedNodeMap(expanded, options); }; /** * **Experimental** * * Merges two or more JSON-LD documents into a single flattened document. * * @param docs the JSON-LD documents to merge together. * @param ctx the context to use to compact the merged result, or null. * @param [options] the options to use: * [base] the base IRI to use. * [expandContext] a context to expand with. * [issuer] a jsonld.IdentifierIssuer to use to label blank nodes. * [mergeNodes] true to merge properties for nodes with the same ID, * false to ignore new properties for nodes with the same ID once * the ID has been defined; note that this may not prevent merging * new properties where a node is in the `object` position * (default: true). * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the merged output. */ jsonld.merge = async function(docs, ctx, options) { if(arguments.length < 1) { throw new TypeError('Could not merge, too few arguments.'); } if(!_isArray(docs)) { throw new TypeError('Could not merge, "docs" must be an array.'); } if(typeof ctx === 'function') { ctx = null; } else { ctx = ctx || null; } // set default options options = _setDefaults(options, { contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // expand all documents const expanded = await Promise.all(docs.map(doc => { const opts = {...options}; return jsonld.expand(doc, opts); })); let mergeNodes = true; if('mergeNodes' in options) { mergeNodes = options.mergeNodes; } const issuer = options.issuer || new IdentifierIssuer('_:b'); const graphs = {'@default': {}}; for(let i = 0; i < expanded.length; ++i) { // uniquely relabel blank nodes const doc = util.relabelBlankNodes(expanded[i], { issuer: new IdentifierIssuer('_:b' + i + '-') }); // add nodes to the shared node map graphs if merging nodes, to a // separate graph set if not const _graphs = (mergeNodes || i === 0) ? graphs : {'@default': {}}; _createNodeMap(doc, _graphs, '@default', issuer); if(_graphs !== graphs) { // merge document graphs but don't merge existing nodes for(const graphName in _graphs) { const _nodeMap = _graphs[graphName]; if(!(graphName in graphs)) { graphs[graphName] = _nodeMap; continue; } const nodeMap = graphs[graphName]; for(const key in _nodeMap) { if(!(key in nodeMap)) { nodeMap[key] = _nodeMap[key]; } } } } } // add all non-default graphs to default graph const defaultGraph = _mergeNodeMaps(graphs); // produce flattened output const flattened = []; const keys = Object.keys(defaultGraph).sort(); for(let ki = 0; ki < keys.length; ++ki) { const node = defaultGraph[keys[ki]]; // only add full subjects to top-level if(!_isSubjectReference(node)) { flattened.push(node); } } if(ctx === null) { return flattened; } // compact result (force @graph option to true, skip expansion) options.graph = true; options.skipExpansion = true; const compacted = await jsonld.compact(flattened, ctx, options); return compacted; }; /** * The default document loader for external documents. * * @param url the URL to load. * * @return a promise that resolves to the remote document. */ Object.defineProperty(jsonld, 'documentLoader', { get: () => jsonld._documentLoader, set: v => jsonld._documentLoader = v }); // default document loader not implemented jsonld.documentLoader = async url => { throw new JsonLdError( 'Could not retrieve a JSON-LD document from the URL. URL ' + 'dereferencing not implemented.', 'jsonld.LoadDocumentError', {code: 'loading document failed', url}); }; /** * Gets a remote JSON-LD document using the default document loader or * one given in the passed options. * * @param url the URL to fetch. * @param [options] the options to use: * [documentLoader] the document loader to use. * * @return a Promise that resolves to the retrieved remote document. */ jsonld.get = async function(url, options) { let load; if(typeof options.documentLoader === 'function') { load = options.documentLoader; } else { load = jsonld.documentLoader; } const remoteDoc = await load(url); try { if(!remoteDoc.document) { throw new JsonLdError( 'No remote document found at the given URL.', 'jsonld.NullRemoteDocument'); } if(_isString(remoteDoc.document)) { remoteDoc.document = JSON.parse(remoteDoc.document); } } catch(e) { throw new JsonLdError( 'Could not retrieve a JSON-LD document from the URL.', 'jsonld.LoadDocumentError', { code: 'loading document failed', cause: e, remoteDoc }); } return remoteDoc; }; /** * Processes a local context, resolving any URLs as necessary, and returns a * new active context. * * @param activeCtx the current active context. * @param localCtx the local context to process. * @param [options] the options to use: * [documentLoader(url, options)] the document loader. * [contextResolver] internal use only. * * @return a Promise that resolves to the new active context. */ jsonld.processContext = async function( activeCtx, localCtx, options) { // set default options options = _setDefaults(options, { base: '', contextResolver: new ContextResolver( {sharedCache: _resolvedContextCache}) }); // return initial context early for null context if(localCtx === null) { return _getInitialContext(options); } // get URLs in localCtx localCtx = util.clone(localCtx); if(!(_isObject(localCtx) && '@context' in localCtx)) { localCtx = {'@context': localCtx}; } return _processContext({activeCtx, localCtx, options}); }; // backwards compatibility jsonld.getContextValue = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js").getContextValue; /** * Document loaders. */ jsonld.documentLoaders = {}; jsonld.documentLoaders.node = __webpack_require__(/*! ./documentLoaders/node */ "./node_modules/jsonld/lib/documentLoaders/node.js"); jsonld.documentLoaders.xhr = __webpack_require__(/*! ./documentLoaders/xhr */ "./node_modules/jsonld/lib/documentLoaders/xhr.js"); /** * Assigns the default document loader for external document URLs to a built-in * default. Supported types currently include: 'xhr' and 'node'. * * @param type the type to set. * @param [params] the parameters required to use the document loader. */ jsonld.useDocumentLoader = function(type) { if(!(type in jsonld.documentLoaders)) { throw new JsonLdError( 'Unknown document loader type: "' + type + '"', 'jsonld.UnknownDocumentLoader', {type}); } // set document loader jsonld.documentLoader = jsonld.documentLoaders[type].apply( jsonld, Array.prototype.slice.call(arguments, 1)); }; /** * Registers an RDF dataset parser by content-type, for use with * jsonld.fromRDF. An RDF dataset parser will always be given one parameter, * a string of input. An RDF dataset parser can be synchronous or * asynchronous (by returning a promise). * * @param contentType the content-type for the parser. * @param parser(input) the parser function (takes a string as a parameter * and either returns an RDF dataset or a Promise that resolves to one. */ jsonld.registerRDFParser = function(contentType, parser) { _rdfParsers[contentType] = parser; }; /** * Unregisters an RDF dataset parser by content-type. * * @param contentType the content-type for the parser. */ jsonld.unregisterRDFParser = function(contentType) { delete _rdfParsers[contentType]; }; // register the N-Quads RDF parser jsonld.registerRDFParser('application/n-quads', NQuads.parse); jsonld.registerRDFParser('application/nquads', NQuads.parse); // register the RDFa API RDF parser jsonld.registerRDFParser('rdfa-api', Rdfa.parse); /* URL API */ jsonld.url = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); /* Utility API */ jsonld.util = util; // backwards compatibility Object.assign(jsonld, util); // reexpose API as jsonld.promises for backwards compatability jsonld.promises = jsonld; // backwards compatibility jsonld.RequestQueue = __webpack_require__(/*! ./RequestQueue */ "./node_modules/jsonld/lib/RequestQueue.js"); /* WebIDL API */ jsonld.JsonLdProcessor = __webpack_require__(/*! ./JsonLdProcessor */ "./node_modules/jsonld/lib/JsonLdProcessor.js")(jsonld); // setup browser global JsonLdProcessor if(_browser && typeof global.JsonLdProcessor === 'undefined') { Object.defineProperty(global, 'JsonLdProcessor', { writable: true, enumerable: false, configurable: true, value: jsonld.JsonLdProcessor }); } // set platform-specific defaults/APIs if(_nodejs) { // use node document loader by default jsonld.useDocumentLoader('node'); } else if(typeof XMLHttpRequest !== 'undefined') { // use xhr document loader by default jsonld.useDocumentLoader('xhr'); } function _setDefaults(options, { documentLoader = jsonld.documentLoader, ...defaults }) { return Object.assign({}, {documentLoader}, defaults, options); } // end of jsonld API `wrapper` factory return jsonld; }; // external APIs: // used to generate a new jsonld API instance const factory = function() { return wrapper(function() { return factory(); }); }; // wrap the main jsonld API instance wrapper(factory); // export API module.exports = factory; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js"), __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"))) /***/ }), /***/ "./node_modules/jsonld/lib/nodeMap.js": /*!********************************************!*\ !*** ./node_modules/jsonld/lib/nodeMap.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const {isKeyword} = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const graphTypes = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); const api = {}; module.exports = api; /** * Creates a merged JSON-LD node map (node ID => node). * * @param input the expanded JSON-LD to create a node map of. * @param [options] the options to use: * [issuer] a jsonld.IdentifierIssuer to use to label blank nodes. * * @return the node map. */ api.createMergedNodeMap = (input, options) => { options = options || {}; // produce a map of all subjects and name each bnode const issuer = options.issuer || new util.IdentifierIssuer('_:b'); const graphs = {'@default': {}}; api.createNodeMap(input, graphs, '@default', issuer); // add all non-default graphs to default graph return api.mergeNodeMaps(graphs); }; /** * Recursively flattens the subjects in the given JSON-LD expanded input * into a node map. * * @param input the JSON-LD expanded input. * @param graphs a map of graph name to subject map. * @param graph the name of the current graph. * @param issuer the blank node identifier issuer. * @param name the name assigned to the current input if it is a bnode. * @param list the list to append to, null for none. */ api.createNodeMap = (input, graphs, graph, issuer, name, list) => { // recurse through array if(types.isArray(input)) { for(const node of input) { api.createNodeMap(node, graphs, graph, issuer, undefined, list); } return; } // add non-object to list if(!types.isObject(input)) { if(list) { list.push(input); } return; } // add values to list if(graphTypes.isValue(input)) { if('@type' in input) { let type = input['@type']; // rename @type blank node if(type.indexOf('_:') === 0) { input['@type'] = type = issuer.getId(type); } } if(list) { list.push(input); } return; } else if(list && graphTypes.isList(input)) { const _list = []; api.createNodeMap(input['@list'], graphs, graph, issuer, name, _list); list.push({'@list': _list}); return; } // Note: At this point, input must be a subject. // spec requires @type to be named first, so assign names early if('@type' in input) { const types = input['@type']; for(const type of types) { if(type.indexOf('_:') === 0) { issuer.getId(type); } } } // get name for subject if(types.isUndefined(name)) { name = graphTypes.isBlankNode(input) ? issuer.getId(input['@id']) : input['@id']; } // add subject reference to list if(list) { list.push({'@id': name}); } // create new subject or merge into existing one const subjects = graphs[graph]; const subject = subjects[name] = subjects[name] || {}; subject['@id'] = name; const properties = Object.keys(input).sort(); for(let property of properties) { // skip @id if(property === '@id') { continue; } // handle reverse properties if(property === '@reverse') { const referencedNode = {'@id': name}; const reverseMap = input['@reverse']; for(const reverseProperty in reverseMap) { const items = reverseMap[reverseProperty]; for(const item of items) { let itemName = item['@id']; if(graphTypes.isBlankNode(item)) { itemName = issuer.getId(itemName); } api.createNodeMap(item, graphs, graph, issuer, itemName); util.addValue( subjects[itemName], reverseProperty, referencedNode, {propertyIsArray: true, allowDuplicate: false}); } } continue; } // recurse into graph if(property === '@graph') { // add graph subjects map entry if(!(name in graphs)) { graphs[name] = {}; } api.createNodeMap(input[property], graphs, name, issuer); continue; } // recurse into included if(property === '@included') { api.createNodeMap(input[property], graphs, graph, issuer); continue; } // copy non-@type keywords if(property !== '@type' && isKeyword(property)) { if(property === '@index' && property in subject && (input[property] !== subject[property] || input[property]['@id'] !== subject[property]['@id'])) { throw new JsonLdError( 'Invalid JSON-LD syntax; conflicting @index property detected.', 'jsonld.SyntaxError', {code: 'conflicting indexes', subject}); } subject[property] = input[property]; continue; } // iterate over objects const objects = input[property]; // if property is a bnode, assign it a new id if(property.indexOf('_:') === 0) { property = issuer.getId(property); } // ensure property is added for empty arrays if(objects.length === 0) { util.addValue(subject, property, [], {propertyIsArray: true}); continue; } for(let o of objects) { if(property === '@type') { // rename @type blank nodes o = (o.indexOf('_:') === 0) ? issuer.getId(o) : o; } // handle embedded subject or subject reference if(graphTypes.isSubject(o) || graphTypes.isSubjectReference(o)) { // skip null @id if('@id' in o && !o['@id']) { continue; } // relabel blank node @id const id = graphTypes.isBlankNode(o) ? issuer.getId(o['@id']) : o['@id']; // add reference and recurse util.addValue( subject, property, {'@id': id}, {propertyIsArray: true, allowDuplicate: false}); api.createNodeMap(o, graphs, graph, issuer, id); } else if(graphTypes.isValue(o)) { util.addValue( subject, property, o, {propertyIsArray: true, allowDuplicate: false}); } else if(graphTypes.isList(o)) { // handle @list const _list = []; api.createNodeMap(o['@list'], graphs, graph, issuer, name, _list); o = {'@list': _list}; util.addValue( subject, property, o, {propertyIsArray: true, allowDuplicate: false}); } else { // handle @value api.createNodeMap(o, graphs, graph, issuer, name); util.addValue( subject, property, o, {propertyIsArray: true, allowDuplicate: false}); } } } }; /** * Merge separate named graphs into a single merged graph including * all nodes from the default graph and named graphs. * * @param graphs a map of graph name to subject map. * * @return the merged graph map. */ api.mergeNodeMapGraphs = graphs => { const merged = {}; for(const name of Object.keys(graphs).sort()) { for(const id of Object.keys(graphs[name]).sort()) { const node = graphs[name][id]; if(!(id in merged)) { merged[id] = {'@id': id}; } const mergedNode = merged[id]; for(const property of Object.keys(node).sort()) { if(isKeyword(property) && property !== '@type') { // copy keywords mergedNode[property] = util.clone(node[property]); } else { // merge objects for(const value of node[property]) { util.addValue( mergedNode, property, util.clone(value), {propertyIsArray: true, allowDuplicate: false}); } } } } } return merged; }; api.mergeNodeMaps = graphs => { // add all non-default graphs to default graph const defaultGraph = graphs['@default']; const graphNames = Object.keys(graphs).sort(); for(const graphName of graphNames) { if(graphName === '@default') { continue; } const nodeMap = graphs[graphName]; let subject = defaultGraph[graphName]; if(!subject) { defaultGraph[graphName] = subject = { '@id': graphName, '@graph': [] }; } else if(!('@graph' in subject)) { subject['@graph'] = []; } const graph = subject['@graph']; for(const id of Object.keys(nodeMap).sort()) { const node = nodeMap[id]; // only add full subjects if(!graphTypes.isSubjectReference(node)) { graph.push(node); } } } return defaultGraph; }; /***/ }), /***/ "./node_modules/jsonld/lib/toRdf.js": /*!******************************************!*\ !*** ./node_modules/jsonld/lib/toRdf.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const {createNodeMap} = __webpack_require__(/*! ./nodeMap */ "./node_modules/jsonld/lib/nodeMap.js"); const {isKeyword} = __webpack_require__(/*! ./context */ "./node_modules/jsonld/lib/context.js"); const graphTypes = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const jsonCanonicalize = __webpack_require__(/*! canonicalize */ "./node_modules/canonicalize/lib/canonicalize.js"); const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.js"); const { // RDF, // RDF_LIST, RDF_FIRST, RDF_REST, RDF_NIL, RDF_TYPE, // RDF_PLAIN_LITERAL, // RDF_XML_LITERAL, RDF_JSON_LITERAL, // RDF_OBJECT, RDF_LANGSTRING, // XSD, XSD_BOOLEAN, XSD_DOUBLE, XSD_INTEGER, XSD_STRING, } = __webpack_require__(/*! ./constants */ "./node_modules/jsonld/lib/constants.js"); const { isAbsolute: _isAbsoluteIri } = __webpack_require__(/*! ./url */ "./node_modules/jsonld/lib/url.js"); const api = {}; module.exports = api; /** * Outputs an RDF dataset for the expanded JSON-LD input. * * @param input the expanded JSON-LD input. * @param options the RDF serialization options. * * @return the RDF dataset. */ api.toRDF = (input, options) => { // create node map for default graph (and any named graphs) const issuer = new util.IdentifierIssuer('_:b'); const nodeMap = {'@default': {}}; createNodeMap(input, nodeMap, '@default', issuer); const dataset = []; const graphNames = Object.keys(nodeMap).sort(); for(const graphName of graphNames) { let graphTerm; if(graphName === '@default') { graphTerm = {termType: 'DefaultGraph', value: ''}; } else if(_isAbsoluteIri(graphName)) { if(graphName.startsWith('_:')) { graphTerm = {termType: 'BlankNode'}; } else { graphTerm = {termType: 'NamedNode'}; } graphTerm.value = graphName; } else { // skip relative IRIs (not valid RDF) continue; } _graphToRDF(dataset, nodeMap[graphName], graphTerm, issuer, options); } return dataset; }; /** * Adds RDF quads for a particular graph to the given dataset. * * @param dataset the dataset to append RDF quads to. * @param graph the graph to create RDF quads for. * @param graphTerm the graph term for each quad. * @param issuer a IdentifierIssuer for assigning blank node names. * @param options the RDF serialization options. * * @return the array of RDF triples for the given graph. */ function _graphToRDF(dataset, graph, graphTerm, issuer, options) { const ids = Object.keys(graph).sort(); for(const id of ids) { const node = graph[id]; const properties = Object.keys(node).sort(); for(let property of properties) { const items = node[property]; if(property === '@type') { property = RDF_TYPE; } else if(isKeyword(property)) { continue; } for(const item of items) { // RDF subject const subject = { termType: id.startsWith('_:') ? 'BlankNode' : 'NamedNode', value: id }; // skip relative IRI subjects (not valid RDF) if(!_isAbsoluteIri(id)) { continue; } // RDF predicate const predicate = { termType: property.startsWith('_:') ? 'BlankNode' : 'NamedNode', value: property }; // skip relative IRI predicates (not valid RDF) if(!_isAbsoluteIri(property)) { continue; } // skip blank node predicates unless producing generalized RDF if(predicate.termType === 'BlankNode' && !options.produceGeneralizedRdf) { continue; } // convert list, value or node object to triple const object = _objectToRDF(item, issuer, dataset, graphTerm, options.rdfDirection); // skip null objects (they are relative IRIs) if(object) { dataset.push({ subject, predicate, object, graph: graphTerm }); } } } } } /** * Converts a @list value into linked list of blank node RDF quads * (an RDF collection). * * @param list the @list value. * @param issuer a IdentifierIssuer for assigning blank node names. * @param dataset the array of quads to append to. * @param graphTerm the graph term for each quad. * * @return the head of the list. */ function _listToRDF(list, issuer, dataset, graphTerm, rdfDirection) { const first = {termType: 'NamedNode', value: RDF_FIRST}; const rest = {termType: 'NamedNode', value: RDF_REST}; const nil = {termType: 'NamedNode', value: RDF_NIL}; const last = list.pop(); // Result is the head of the list const result = last ? {termType: 'BlankNode', value: issuer.getId()} : nil; let subject = result; for(const item of list) { const object = _objectToRDF(item, issuer, dataset, graphTerm, rdfDirection); const next = {termType: 'BlankNode', value: issuer.getId()}; dataset.push({ subject, predicate: first, object, graph: graphTerm }); dataset.push({ subject, predicate: rest, object: next, graph: graphTerm }); subject = next; } // Tail of list if(last) { const object = _objectToRDF(last, issuer, dataset, graphTerm, rdfDirection); dataset.push({ subject, predicate: first, object, graph: graphTerm }); dataset.push({ subject, predicate: rest, object: nil, graph: graphTerm }); } return result; } /** * Converts a JSON-LD value object to an RDF literal or a JSON-LD string, * node object to an RDF resource, or adds a list. * * @param item the JSON-LD value or node object. * @param issuer a IdentifierIssuer for assigning blank node names. * @param dataset the dataset to append RDF quads to. * @param graphTerm the graph term for each quad. * * @return the RDF literal or RDF resource. */ function _objectToRDF(item, issuer, dataset, graphTerm, rdfDirection) { const object = {}; // convert value object to RDF if(graphTypes.isValue(item)) { object.termType = 'Literal'; object.value = undefined; object.datatype = { termType: 'NamedNode' }; let value = item['@value']; const datatype = item['@type'] || null; // convert to XSD/JSON datatypes as appropriate if(datatype === '@json') { object.value = jsonCanonicalize(value); object.datatype.value = RDF_JSON_LITERAL; } else if(types.isBoolean(value)) { object.value = value.toString(); object.datatype.value = datatype || XSD_BOOLEAN; } else if(types.isDouble(value) || datatype === XSD_DOUBLE) { if(!types.isDouble(value)) { value = parseFloat(value); } // canonical double representation object.value = value.toExponential(15).replace(/(\d)0*e\+?/, '$1E'); object.datatype.value = datatype || XSD_DOUBLE; } else if(types.isNumber(value)) { object.value = value.toFixed(0); object.datatype.value = datatype || XSD_INTEGER; } else if(rdfDirection === 'i18n-datatype' && '@direction' in item) { const datatype = 'https://www.w3.org/ns/i18n#' + (item['@language'] || '') + `_${item['@direction']}`; object.datatype.value = datatype; object.value = value; } else if('@language' in item) { object.value = value; object.datatype.value = datatype || RDF_LANGSTRING; object.language = item['@language']; } else { object.value = value; object.datatype.value = datatype || XSD_STRING; } } else if(graphTypes.isList(item)) { const _list = _listToRDF(item['@list'], issuer, dataset, graphTerm, rdfDirection); object.termType = _list.termType; object.value = _list.value; } else { // convert string/node object to RDF const id = types.isObject(item) ? item['@id'] : item; object.termType = id.startsWith('_:') ? 'BlankNode' : 'NamedNode'; object.value = id; } // skip relative IRIs, not valid RDF if(object.termType === 'NamedNode' && !_isAbsoluteIri(object.value)) { return null; } return object; } /***/ }), /***/ "./node_modules/jsonld/lib/types.js": /*!******************************************!*\ !*** ./node_modules/jsonld/lib/types.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const api = {}; module.exports = api; /** * Returns true if the given value is an Array. * * @param v the value to check. * * @return true if the value is an Array, false if not. */ api.isArray = Array.isArray; /** * Returns true if the given value is a Boolean. * * @param v the value to check. * * @return true if the value is a Boolean, false if not. */ api.isBoolean = v => (typeof v === 'boolean' || Object.prototype.toString.call(v) === '[object Boolean]'); /** * Returns true if the given value is a double. * * @param v the value to check. * * @return true if the value is a double, false if not. */ api.isDouble = v => api.isNumber(v) && (String(v).indexOf('.') !== -1 || Math.abs(v) >= 1e21); /** * Returns true if the given value is an empty Object. * * @param v the value to check. * * @return true if the value is an empty Object, false if not. */ api.isEmptyObject = v => api.isObject(v) && Object.keys(v).length === 0; /** * Returns true if the given value is a Number. * * @param v the value to check. * * @return true if the value is a Number, false if not. */ api.isNumber = v => (typeof v === 'number' || Object.prototype.toString.call(v) === '[object Number]'); /** * Returns true if the given value is numeric. * * @param v the value to check. * * @return true if the value is numeric, false if not. */ api.isNumeric = v => !isNaN(parseFloat(v)) && isFinite(v); /** * Returns true if the given value is an Object. * * @param v the value to check. * * @return true if the value is an Object, false if not. */ api.isObject = v => Object.prototype.toString.call(v) === '[object Object]'; /** * Returns true if the given value is a String. * * @param v the value to check. * * @return true if the value is a String, false if not. */ api.isString = v => (typeof v === 'string' || Object.prototype.toString.call(v) === '[object String]'); /** * Returns true if the given value is undefined. * * @param v the value to check. * * @return true if the value is undefined, false if not. */ api.isUndefined = v => typeof v === 'undefined'; /***/ }), /***/ "./node_modules/jsonld/lib/url.js": /*!****************************************!*\ !*** ./node_modules/jsonld/lib/url.js ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved. */ const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); const api = {}; module.exports = api; // define URL parser // parseUri 1.2.2 // (c) Steven Levithan // MIT License // with local jsonld.js modifications api.parsers = { simple: { // RFC 3986 basic parts keys: [ 'href', 'scheme', 'authority', 'path', 'query', 'fragment' ], /* eslint-disable-next-line max-len */ regex: /^(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/ }, full: { keys: [ 'href', 'protocol', 'scheme', 'authority', 'auth', 'user', 'password', 'hostname', 'port', 'path', 'directory', 'file', 'query', 'fragment' ], /* eslint-disable-next-line max-len */ regex: /^(([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?(?:(((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/ } }; api.parse = (str, parser) => { const parsed = {}; const o = api.parsers[parser || 'full']; const m = o.regex.exec(str); let i = o.keys.length; while(i--) { parsed[o.keys[i]] = (m[i] === undefined) ? null : m[i]; } // remove default ports in found in URLs if((parsed.scheme === 'https' && parsed.port === '443') || (parsed.scheme === 'http' && parsed.port === '80')) { parsed.href = parsed.href.replace(':' + parsed.port, ''); parsed.authority = parsed.authority.replace(':' + parsed.port, ''); parsed.port = null; } parsed.normalizedPath = api.removeDotSegments(parsed.path); return parsed; }; /** * Prepends a base IRI to the given relative IRI. * * @param base the base IRI. * @param iri the relative IRI. * * @return the absolute IRI. */ api.prependBase = (base, iri) => { // skip IRI processing if(base === null) { return iri; } // already an absolute IRI if(api.isAbsolute(iri)) { return iri; } // parse base if it is a string if(!base || types.isString(base)) { base = api.parse(base || ''); } // parse given IRI const rel = api.parse(iri); // per RFC3986 5.2.2 const transform = { protocol: base.protocol || '' }; if(rel.authority !== null) { transform.authority = rel.authority; transform.path = rel.path; transform.query = rel.query; } else { transform.authority = base.authority; if(rel.path === '') { transform.path = base.path; if(rel.query !== null) { transform.query = rel.query; } else { transform.query = base.query; } } else { if(rel.path.indexOf('/') === 0) { // IRI represents an absolute path transform.path = rel.path; } else { // merge paths let path = base.path; // append relative path to the end of the last directory from base path = path.substr(0, path.lastIndexOf('/') + 1); if((path.length > 0 || base.authority) && path.substr(-1) !== '/') { path += '/'; } path += rel.path; transform.path = path; } transform.query = rel.query; } } if(rel.path !== '') { // remove slashes and dots in path transform.path = api.removeDotSegments(transform.path); } // construct URL let rval = transform.protocol; if(transform.authority !== null) { rval += '//' + transform.authority; } rval += transform.path; if(transform.query !== null) { rval += '?' + transform.query; } if(rel.fragment !== null) { rval += '#' + rel.fragment; } // handle empty base if(rval === '') { rval = './'; } return rval; }; /** * Removes a base IRI from the given absolute IRI. * * @param base the base IRI. * @param iri the absolute IRI. * * @return the relative IRI if relative to base, otherwise the absolute IRI. */ api.removeBase = (base, iri) => { // skip IRI processing if(base === null) { return iri; } if(!base || types.isString(base)) { base = api.parse(base || ''); } // establish base root let root = ''; if(base.href !== '') { root += (base.protocol || '') + '//' + (base.authority || ''); } else if(iri.indexOf('//')) { // support network-path reference with empty base root += '//'; } // IRI not relative to base if(iri.indexOf(root) !== 0) { return iri; } // remove root from IRI and parse remainder const rel = api.parse(iri.substr(root.length)); // remove path segments that match (do not remove last segment unless there // is a hash or query) const baseSegments = base.normalizedPath.split('/'); const iriSegments = rel.normalizedPath.split('/'); const last = (rel.fragment || rel.query) ? 0 : 1; while(baseSegments.length > 0 && iriSegments.length > last) { if(baseSegments[0] !== iriSegments[0]) { break; } baseSegments.shift(); iriSegments.shift(); } // use '../' for each non-matching base segment let rval = ''; if(baseSegments.length > 0) { // don't count the last segment (if it ends with '/' last path doesn't // count and if it doesn't end with '/' it isn't a path) baseSegments.pop(); for(let i = 0; i < baseSegments.length; ++i) { rval += '../'; } } // prepend remaining segments rval += iriSegments.join('/'); // add query and hash if(rel.query !== null) { rval += '?' + rel.query; } if(rel.fragment !== null) { rval += '#' + rel.fragment; } // handle empty base if(rval === '') { rval = './'; } return rval; }; /** * Removes dot segments from a URL path. * * @param path the path to remove dot segments from. */ api.removeDotSegments = path => { // RFC 3986 5.2.4 (reworked) // empty path shortcut if(path.length === 0) { return ''; } const input = path.split('/'); const output = []; while(input.length > 0) { const next = input.shift(); const done = input.length === 0; if(next === '.') { if(done) { // ensure output has trailing / output.push(''); } continue; } if(next === '..') { output.pop(); if(done) { // ensure output has trailing / output.push(''); } continue; } output.push(next); } // if path was absolute, ensure output has leading / if(path[0] === '/' && output.length > 0 && output[0] !== '') { output.unshift(''); } if(output.length === 1 && output[0] === '') { return '/'; } return output.join('/'); }; // TODO: time better isAbsolute/isRelative checks using full regexes: // http://jmrware.com/articles/2009/uri_regexp/URI_regex.html // regex to check for absolute IRI (starting scheme and ':') or blank node IRI const isAbsoluteRegex = /^([A-Za-z][A-Za-z0-9+-.]*|_):[^\s]*$/; /** * Returns true if the given value is an absolute IRI or blank node IRI, false * if not. * Note: This weak check only checks for a correct starting scheme. * * @param v the value to check. * * @return true if the value is an absolute IRI, false if not. */ api.isAbsolute = v => types.isString(v) && isAbsoluteRegex.test(v); /** * Returns true if the given value is a relative IRI, false if not. * Note: this is a weak check. * * @param v the value to check. * * @return true if the value is a relative IRI, false if not. */ api.isRelative = v => types.isString(v); /***/ }), /***/ "./node_modules/jsonld/lib/util.js": /*!*****************************************!*\ !*** ./node_modules/jsonld/lib/util.js ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2017-2019 Digital Bazaar, Inc. All rights reserved. */ const graphTypes = __webpack_require__(/*! ./graphTypes */ "./node_modules/jsonld/lib/graphTypes.js"); const types = __webpack_require__(/*! ./types */ "./node_modules/jsonld/lib/types.js"); // TODO: move `IdentifierIssuer` to its own package const IdentifierIssuer = __webpack_require__(/*! rdf-canonize */ "./node_modules/rdf-canonize/lib/index.js").IdentifierIssuer; const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js"); // constants const REGEX_LINK_HEADERS = /(?:<[^>]*?>|"[^"]*?"|[^,])+/g; const REGEX_LINK_HEADER = /\s*<([^>]*?)>\s*(?:;\s*(.*))?/; const REGEX_LINK_HEADER_PARAMS = /(.*?)=(?:(?:"([^"]*?)")|([^"]*?))\s*(?:(?:;\s*)|$)/g; const DEFAULTS = { headers: { accept: 'application/ld+json, application/json' } }; const api = {}; module.exports = api; api.IdentifierIssuer = IdentifierIssuer; /** * Clones an object, array, Map, Set, or string/number. If a typed JavaScript * object is given, such as a Date, it will be converted to a string. * * @param value the value to clone. * * @return the cloned value. */ api.clone = function(value) { if(value && typeof value === 'object') { let rval; if(types.isArray(value)) { rval = []; for(let i = 0; i < value.length; ++i) { rval[i] = api.clone(value[i]); } } else if(value instanceof Map) { rval = new Map(); for(const [k, v] of value) { rval.set(k, api.clone(v)); } } else if(value instanceof Set) { rval = new Set(); for(const v of value) { rval.add(api.clone(v)); } } else if(types.isObject(value)) { rval = {}; for(const key in value) { rval[key] = api.clone(value[key]); } } else { rval = value.toString(); } return rval; } return value; }; /** * Ensure a value is an array. If the value is an array, it is returned. * Otherwise, it is wrapped in an array. * * @param value the value to return as an array. * * @return the value as an array. */ api.asArray = function(value) { return Array.isArray(value) ? value : [value]; }; /** * Builds an HTTP headers object for making a JSON-LD request from custom * headers and asserts the `accept` header isn't overridden. * * @param headers an object of headers with keys as header names and values * as header values. * * @return an object of headers with a valid `accept` header. */ api.buildHeaders = (headers = {}) => { const hasAccept = Object.keys(headers).some( h => h.toLowerCase() === 'accept'); if(hasAccept) { throw new RangeError( 'Accept header may not be specified; only "' + DEFAULTS.headers.accept + '" is supported.'); } return Object.assign({Accept: DEFAULTS.headers.accept}, headers); }; /** * Parses a link header. The results will be key'd by the value of "rel". * * Link: ; * rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" * * Parses as: { * 'http://www.w3.org/ns/json-ld#context': { * target: http://json-ld.org/contexts/person.jsonld, * type: 'application/ld+json' * } * } * * If there is more than one "rel" with the same IRI, then entries in the * resulting map for that "rel" will be arrays. * * @param header the link header to parse. */ api.parseLinkHeader = header => { const rval = {}; // split on unbracketed/unquoted commas const entries = header.match(REGEX_LINK_HEADERS); for(let i = 0; i < entries.length; ++i) { let match = entries[i].match(REGEX_LINK_HEADER); if(!match) { continue; } const result = {target: match[1]}; const params = match[2]; while((match = REGEX_LINK_HEADER_PARAMS.exec(params))) { result[match[1]] = (match[2] === undefined) ? match[3] : match[2]; } const rel = result['rel'] || ''; if(Array.isArray(rval[rel])) { rval[rel].push(result); } else if(rval.hasOwnProperty(rel)) { rval[rel] = [rval[rel], result]; } else { rval[rel] = result; } } return rval; }; /** * Throws an exception if the given value is not a valid @type value. * * @param v the value to check. */ api.validateTypeValue = (v, isFrame) => { if(types.isString(v)) { return; } if(types.isArray(v) && v.every(vv => types.isString(vv))) { return; } if(isFrame && types.isObject(v)) { switch(Object.keys(v).length) { case 0: // empty object is wildcard return; case 1: // default entry is all strings if('@default' in v && api.asArray(v['@default']).every(vv => types.isString(vv))) { return; } } } throw new JsonLdError( 'Invalid JSON-LD syntax; "@type" value must a string, an array of ' + 'strings, an empty object, ' + 'or a default object.', 'jsonld.SyntaxError', {code: 'invalid type value', value: v}); }; /** * Returns true if the given subject has the given property. * * @param subject the subject to check. * @param property the property to look for. * * @return true if the subject has the given property, false if not. */ api.hasProperty = (subject, property) => { if(subject.hasOwnProperty(property)) { const value = subject[property]; return (!types.isArray(value) || value.length > 0); } return false; }; /** * Determines if the given value is a property of the given subject. * * @param subject the subject to check. * @param property the property to check. * @param value the value to check. * * @return true if the value exists, false if not. */ api.hasValue = (subject, property, value) => { if(api.hasProperty(subject, property)) { let val = subject[property]; const isList = graphTypes.isList(val); if(types.isArray(val) || isList) { if(isList) { val = val['@list']; } for(let i = 0; i < val.length; ++i) { if(api.compareValues(value, val[i])) { return true; } } } else if(!types.isArray(value)) { // avoid matching the set of values with an array value parameter return api.compareValues(value, val); } } return false; }; /** * Adds a value to a subject. If the value is an array, all values in the * array will be added. * * @param subject the subject to add the value to. * @param property the property that relates the value to the subject. * @param value the value to add. * @param [options] the options to use: * [propertyIsArray] true if the property is always an array, false * if not (default: false). * [valueIsArray] true if the value to be added should be preserved as * an array (lists) (default: false). * [allowDuplicate] true to allow duplicates, false not to (uses a * simple shallow comparison of subject ID or value) (default: true). * [prependValue] false to prepend value to any existing values. * (default: false) */ api.addValue = (subject, property, value, options) => { options = options || {}; if(!('propertyIsArray' in options)) { options.propertyIsArray = false; } if(!('valueIsArray' in options)) { options.valueIsArray = false; } if(!('allowDuplicate' in options)) { options.allowDuplicate = true; } if(!('prependValue' in options)) { options.prependValue = false; } if(options.valueIsArray) { subject[property] = value; } else if(types.isArray(value)) { if(value.length === 0 && options.propertyIsArray && !subject.hasOwnProperty(property)) { subject[property] = []; } if(options.prependValue) { value = value.concat(subject[property]); subject[property] = []; } for(let i = 0; i < value.length; ++i) { api.addValue(subject, property, value[i], options); } } else if(subject.hasOwnProperty(property)) { // check if subject already has value if duplicates not allowed const hasValue = (!options.allowDuplicate && api.hasValue(subject, property, value)); // make property an array if value not present or always an array if(!types.isArray(subject[property]) && (!hasValue || options.propertyIsArray)) { subject[property] = [subject[property]]; } // add new value if(!hasValue) { if(options.prependValue) { subject[property].unshift(value); } else { subject[property].push(value); } } } else { // add new value as set or single value subject[property] = options.propertyIsArray ? [value] : value; } }; /** * Gets all of the values for a subject's property as an array. * * @param subject the subject. * @param property the property. * * @return all of the values for a subject's property as an array. */ api.getValues = (subject, property) => [].concat(subject[property] || []); /** * Removes a property from a subject. * * @param subject the subject. * @param property the property. */ api.removeProperty = (subject, property) => { delete subject[property]; }; /** * Removes a value from a subject. * * @param subject the subject. * @param property the property that relates the value to the subject. * @param value the value to remove. * @param [options] the options to use: * [propertyIsArray] true if the property is always an array, false * if not (default: false). */ api.removeValue = (subject, property, value, options) => { options = options || {}; if(!('propertyIsArray' in options)) { options.propertyIsArray = false; } // filter out value const values = api.getValues(subject, property).filter( e => !api.compareValues(e, value)); if(values.length === 0) { api.removeProperty(subject, property); } else if(values.length === 1 && !options.propertyIsArray) { subject[property] = values[0]; } else { subject[property] = values; } }; /** * Relabels all blank nodes in the given JSON-LD input. * * @param input the JSON-LD input. * @param [options] the options to use: * [issuer] an IdentifierIssuer to use to label blank nodes. */ api.relabelBlankNodes = (input, options) => { options = options || {}; const issuer = options.issuer || new IdentifierIssuer('_:b'); return _labelBlankNodes(issuer, input); }; /** * Compares two JSON-LD values for equality. Two JSON-LD values will be * considered equal if: * * 1. They are both primitives of the same type and value. * 2. They are both @values with the same @value, @type, @language, * and @index, OR * 3. They both have @ids they are the same. * * @param v1 the first value. * @param v2 the second value. * * @return true if v1 and v2 are considered equal, false if not. */ api.compareValues = (v1, v2) => { // 1. equal primitives if(v1 === v2) { return true; } // 2. equal @values if(graphTypes.isValue(v1) && graphTypes.isValue(v2) && v1['@value'] === v2['@value'] && v1['@type'] === v2['@type'] && v1['@language'] === v2['@language'] && v1['@index'] === v2['@index']) { return true; } // 3. equal @ids if(types.isObject(v1) && ('@id' in v1) && types.isObject(v2) && ('@id' in v2)) { return v1['@id'] === v2['@id']; } return false; }; /** * Compares two strings first based on length and then lexicographically. * * @param a the first string. * @param b the second string. * * @return -1 if a < b, 1 if a > b, 0 if a === b. */ api.compareShortestLeast = (a, b) => { if(a.length < b.length) { return -1; } if(b.length < a.length) { return 1; } if(a === b) { return 0; } return (a < b) ? -1 : 1; }; /** * Labels the blank nodes in the given value using the given IdentifierIssuer. * * @param issuer the IdentifierIssuer to use. * @param element the element with blank nodes to rename. * * @return the element. */ function _labelBlankNodes(issuer, element) { if(types.isArray(element)) { for(let i = 0; i < element.length; ++i) { element[i] = _labelBlankNodes(issuer, element[i]); } } else if(graphTypes.isList(element)) { element['@list'] = _labelBlankNodes(issuer, element['@list']); } else if(types.isObject(element)) { // relabel blank node if(graphTypes.isBlankNode(element)) { element['@id'] = issuer.getId(element['@id']); } // recursively apply to all keys const keys = Object.keys(element).sort(); for(let ki = 0; ki < keys.length; ++ki) { const key = keys[ki]; if(key !== '@id') { element[key] = _labelBlankNodes(issuer, element[key]); } } } return element; } /***/ }), /***/ "./node_modules/jss-plugin-camel-case/dist/jss-plugin-camel-case.esm.js": /*!******************************************************************************!*\ !*** ./node_modules/jss-plugin-camel-case/dist/jss-plugin-camel-case.esm.js ***! \******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var hyphenate_style_name__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! hyphenate-style-name */ "./node_modules/hyphenate-style-name/index.js"); /** * Convert camel cased property names to dash separated. * * @param {Object} style * @return {Object} */ function convertCase(style) { var converted = {}; for (var prop in style) { var key = prop.indexOf('--') === 0 ? prop : Object(hyphenate_style_name__WEBPACK_IMPORTED_MODULE_0__["default"])(prop); converted[key] = style[prop]; } if (style.fallbacks) { if (Array.isArray(style.fallbacks)) converted.fallbacks = style.fallbacks.map(convertCase);else converted.fallbacks = convertCase(style.fallbacks); } return converted; } /** * Allow camel cased property names by converting them back to dasherized. * * @param {Rule} rule */ function camelCase() { function onProcessStyle(style) { if (Array.isArray(style)) { // Handle rules like @font-face, which can have multiple styles in an array for (var index = 0; index < style.length; index++) { style[index] = convertCase(style[index]); } return style; } return convertCase(style); } function onChangeValue(value, prop, rule) { if (prop.indexOf('--') === 0) { return value; } var hyphenatedProp = Object(hyphenate_style_name__WEBPACK_IMPORTED_MODULE_0__["default"])(prop); // There was no camel case in place if (prop === hyphenatedProp) return value; rule.prop(hyphenatedProp, value); // Core will ignore that property value we set the proper one above. return null; } return { onProcessStyle: onProcessStyle, onChangeValue: onChangeValue }; } /* harmony default export */ __webpack_exports__["default"] = (camelCase); /***/ }), /***/ "./node_modules/jss-plugin-compose/dist/jss-plugin-compose.esm.js": /*!************************************************************************!*\ !*** ./node_modules/jss-plugin-compose/dist/jss-plugin-compose.esm.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); /** * Set selector. * * @param {Object} original rule * @param {String} className class string * @return {Boolean} flag, indicating function was successfull or not */ function registerClass(rule, className) { // Skip falsy values if (!className) return true; // Support array of class names `{composes: ['foo', 'bar']}` if (Array.isArray(className)) { for (var index = 0; index < className.length; index++) { var isSetted = registerClass(rule, className[index]); if (!isSetted) return false; } return true; } // Support space separated class names `{composes: 'foo bar'}` if (className.indexOf(' ') > -1) { return registerClass(rule, className.split(' ')); } var _ref = rule.options, parent = _ref.parent; // It is a ref to a local rule. if (className[0] === '$') { var refRule = parent.getRule(className.substr(1)); if (!refRule) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_0__["default"])(false, "[JSS] Referenced rule is not defined. \n" + rule.toString()) : undefined; return false; } if (refRule === rule) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_0__["default"])(false, "[JSS] Cyclic composition detected. \n" + rule.toString()) : undefined; return false; } parent.classes[rule.key] += " " + parent.classes[refRule.key]; return true; } parent.classes[rule.key] += " " + className; return true; } /** * Convert compose property to additional class, remove property from original styles. * * @param {Rule} rule * @api public */ function jssCompose() { function onProcessStyle(style, rule) { if (!('composes' in style)) return style; registerClass(rule, style.composes); // Remove composes property to prevent infinite loop. delete style.composes; return style; } return { onProcessStyle: onProcessStyle }; } /* harmony default export */ __webpack_exports__["default"] = (jssCompose); /***/ }), /***/ "./node_modules/jss-plugin-default-unit/dist/jss-plugin-default-unit.esm.js": /*!**********************************************************************************!*\ !*** ./node_modules/jss-plugin-default-unit/dist/jss-plugin-default-unit.esm.js ***! \**********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); var px = jss__WEBPACK_IMPORTED_MODULE_0__["hasCSSTOMSupport"] && CSS ? CSS.px : 'px'; var ms = jss__WEBPACK_IMPORTED_MODULE_0__["hasCSSTOMSupport"] && CSS ? CSS.ms : 'ms'; var percent = jss__WEBPACK_IMPORTED_MODULE_0__["hasCSSTOMSupport"] && CSS ? CSS.percent : '%'; /** * Generated jss-plugin-default-unit CSS property units * * @type object */ var defaultUnits = { // Animation properties 'animation-delay': ms, 'animation-duration': ms, // Background properties 'background-position': px, 'background-position-x': px, 'background-position-y': px, 'background-size': px, // Border Properties border: px, 'border-bottom': px, 'border-bottom-left-radius': px, 'border-bottom-right-radius': px, 'border-bottom-width': px, 'border-left': px, 'border-left-width': px, 'border-radius': px, 'border-right': px, 'border-right-width': px, 'border-top': px, 'border-top-left-radius': px, 'border-top-right-radius': px, 'border-top-width': px, 'border-width': px, 'border-block': px, 'border-block-end': px, 'border-block-end-width': px, 'border-block-start': px, 'border-block-start-width': px, 'border-block-width': px, 'border-inline': px, 'border-inline-end': px, 'border-inline-end-width': px, 'border-inline-start': px, 'border-inline-start-width': px, 'border-inline-width': px, 'border-start-start-radius': px, 'border-start-end-radius': px, 'border-end-start-radius': px, 'border-end-end-radius': px, // Margin properties margin: px, 'margin-bottom': px, 'margin-left': px, 'margin-right': px, 'margin-top': px, 'margin-block': px, 'margin-block-end': px, 'margin-block-start': px, 'margin-inline': px, 'margin-inline-end': px, 'margin-inline-start': px, // Padding properties padding: px, 'padding-bottom': px, 'padding-left': px, 'padding-right': px, 'padding-top': px, 'padding-block': px, 'padding-block-end': px, 'padding-block-start': px, 'padding-inline': px, 'padding-inline-end': px, 'padding-inline-start': px, // Mask properties 'mask-position-x': px, 'mask-position-y': px, 'mask-size': px, // Width and height properties height: px, width: px, 'min-height': px, 'max-height': px, 'min-width': px, 'max-width': px, // Position properties bottom: px, left: px, top: px, right: px, inset: px, 'inset-block': px, 'inset-block-end': px, 'inset-block-start': px, 'inset-inline': px, 'inset-inline-end': px, 'inset-inline-start': px, // Shadow properties 'box-shadow': px, 'text-shadow': px, // Column properties 'column-gap': px, 'column-rule': px, 'column-rule-width': px, 'column-width': px, // Font and text properties 'font-size': px, 'font-size-delta': px, 'letter-spacing': px, 'text-decoration-thickness': px, 'text-indent': px, 'text-stroke': px, 'text-stroke-width': px, 'word-spacing': px, // Motion properties motion: px, 'motion-offset': px, // Outline properties outline: px, 'outline-offset': px, 'outline-width': px, // Perspective properties perspective: px, 'perspective-origin-x': percent, 'perspective-origin-y': percent, // Transform properties 'transform-origin': percent, 'transform-origin-x': percent, 'transform-origin-y': percent, 'transform-origin-z': percent, // Transition properties 'transition-delay': ms, 'transition-duration': ms, // Alignment properties 'vertical-align': px, 'flex-basis': px, // Some random properties 'shape-margin': px, size: px, gap: px, // Grid properties grid: px, 'grid-gap': px, 'row-gap': px, 'grid-row-gap': px, 'grid-column-gap': px, 'grid-template-rows': px, 'grid-template-columns': px, 'grid-auto-rows': px, 'grid-auto-columns': px, // Not existing properties. // Used to avoid issues with jss-plugin-expand integration. 'box-shadow-x': px, 'box-shadow-y': px, 'box-shadow-blur': px, 'box-shadow-spread': px, 'font-line-height': px, 'text-shadow-x': px, 'text-shadow-y': px, 'text-shadow-blur': px }; /** * Clones the object and adds a camel cased property version. */ function addCamelCasedVersion(obj) { var regExp = /(-[a-z])/g; var replace = function replace(str) { return str[1].toUpperCase(); }; var newObj = {}; for (var _key in obj) { newObj[_key] = obj[_key]; newObj[_key.replace(regExp, replace)] = obj[_key]; } return newObj; } var units = addCamelCasedVersion(defaultUnits); /** * Recursive deep style passing function */ function iterate(prop, value, options) { if (value == null) return value; if (Array.isArray(value)) { for (var i = 0; i < value.length; i++) { value[i] = iterate(prop, value[i], options); } } else if (typeof value === 'object') { if (prop === 'fallbacks') { for (var innerProp in value) { value[innerProp] = iterate(innerProp, value[innerProp], options); } } else { for (var _innerProp in value) { value[_innerProp] = iterate(prop + "-" + _innerProp, value[_innerProp], options); } } } else if (typeof value === 'number' && !Number.isNaN(value)) { var unit = options[prop] || units[prop]; // Add the unit if available, except for the special case of 0px. if (unit && !(value === 0 && unit === px)) { return typeof unit === 'function' ? unit(value).toString() : "" + value + unit; } return value.toString(); } return value; } /** * Add unit to numeric values. */ function defaultUnit(options) { if (options === void 0) { options = {}; } var camelCasedOptions = addCamelCasedVersion(options); function onProcessStyle(style, rule) { if (rule.type !== 'style') return style; for (var prop in style) { style[prop] = iterate(prop, style[prop], camelCasedOptions); } return style; } function onChangeValue(value, prop) { return iterate(prop, value, camelCasedOptions); } return { onProcessStyle: onProcessStyle, onChangeValue: onChangeValue }; } /* harmony default export */ __webpack_exports__["default"] = (defaultUnit); /***/ }), /***/ "./node_modules/jss-plugin-expand/dist/jss-plugin-expand.esm.js": /*!**********************************************************************!*\ !*** ./node_modules/jss-plugin-expand/dist/jss-plugin-expand.esm.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /** * A scheme for converting properties from array to regular style. * All properties listed below will be transformed to a string separated by space. */ var propArray = { 'background-size': true, 'background-position': true, border: true, 'border-bottom': true, 'border-left': true, 'border-top': true, 'border-right': true, 'border-radius': true, 'border-image': true, 'border-width': true, 'border-style': true, 'border-color': true, 'box-shadow': true, flex: true, margin: true, padding: true, outline: true, 'transform-origin': true, transform: true, transition: true /** * A scheme for converting arrays to regular styles inside of objects. * For e.g.: "{position: [0, 0]}" => "background-position: 0 0;". */ }; var propArrayInObj = { position: true, // background-position size: true // background-size /** * A scheme for parsing and building correct styles from passed objects. */ }; var propObj = { padding: { top: 0, right: 0, bottom: 0, left: 0 }, margin: { top: 0, right: 0, bottom: 0, left: 0 }, background: { attachment: null, color: null, image: null, position: null, repeat: null }, border: { width: null, style: null, color: null }, 'border-top': { width: null, style: null, color: null }, 'border-right': { width: null, style: null, color: null }, 'border-bottom': { width: null, style: null, color: null }, 'border-left': { width: null, style: null, color: null }, outline: { width: null, style: null, color: null }, 'list-style': { type: null, position: null, image: null }, transition: { property: null, duration: null, 'timing-function': null, timingFunction: null, // Needed for avoiding comilation issues with jss-plugin-camel-case delay: null }, animation: { name: null, duration: null, 'timing-function': null, timingFunction: null, // Needed to avoid compilation issues with jss-plugin-camel-case delay: null, 'iteration-count': null, iterationCount: null, // Needed to avoid compilation issues with jss-plugin-camel-case direction: null, 'fill-mode': null, fillMode: null, // Needed to avoid compilation issues with jss-plugin-camel-case 'play-state': null, playState: null // Needed to avoid compilation issues with jss-plugin-camel-case }, 'box-shadow': { x: 0, y: 0, blur: 0, spread: 0, color: null, inset: null }, 'text-shadow': { x: 0, y: 0, blur: null, color: null } /** * A scheme for converting non-standart properties inside object. * For e.g.: include 'border-radius' property inside 'border' object. */ }; var customPropObj = { border: { radius: 'border-radius', image: 'border-image', width: 'border-width', style: 'border-style', color: 'border-color' }, 'border-bottom': { width: 'border-bottom-width', style: 'border-bottom-style', color: 'border-bottom-color' }, 'border-top': { width: 'border-top-width', style: 'border-top-style', color: 'border-top-color' }, 'border-left': { width: 'border-left-width', style: 'border-left-style', color: 'border-left-color' }, 'border-right': { width: 'border-right-width', style: 'border-right-style', color: 'border-right-color' }, background: { size: 'background-size', image: 'background-image' }, font: { style: 'font-style', variant: 'font-variant', weight: 'font-weight', stretch: 'font-stretch', size: 'font-size', family: 'font-family', lineHeight: 'line-height', // Needed to avoid compilation issues with jss-plugin-camel-case 'line-height': 'line-height' }, flex: { grow: 'flex-grow', basis: 'flex-basis', direction: 'flex-direction', wrap: 'flex-wrap', flow: 'flex-flow', shrink: 'flex-shrink' }, align: { self: 'align-self', items: 'align-items', content: 'align-content' }, grid: { 'template-columns': 'grid-template-columns', templateColumns: 'grid-template-columns', 'template-rows': 'grid-template-rows', templateRows: 'grid-template-rows', 'template-areas': 'grid-template-areas', templateAreas: 'grid-template-areas', template: 'grid-template', 'auto-columns': 'grid-auto-columns', autoColumns: 'grid-auto-columns', 'auto-rows': 'grid-auto-rows', autoRows: 'grid-auto-rows', 'auto-flow': 'grid-auto-flow', autoFlow: 'grid-auto-flow', row: 'grid-row', column: 'grid-column', 'row-start': 'grid-row-start', rowStart: 'grid-row-start', 'row-end': 'grid-row-end', rowEnd: 'grid-row-end', 'column-start': 'grid-column-start', columnStart: 'grid-column-start', 'column-end': 'grid-column-end', columnEnd: 'grid-column-end', area: 'grid-area', gap: 'grid-gap', 'row-gap': 'grid-row-gap', rowGap: 'grid-row-gap', 'column-gap': 'grid-column-gap', columnGap: 'grid-column-gap' } }; /* eslint-disable no-use-before-define */ /** * Map values by given prop. * * @param {Array} array of values * @param {String} original property * @param {String} original rule * @return {String} mapped values */ function mapValuesByProp(value, prop, rule) { return value.map(function (item) { return objectToArray(item, prop, rule, false, true); }); } /** * Convert array to nested array, if needed */ function processArray(value, prop, scheme, rule) { if (scheme[prop] == null) return value; if (value.length === 0) return []; if (Array.isArray(value[0])) return processArray(value[0], prop, scheme, rule); if (typeof value[0] === 'object') { return mapValuesByProp(value, prop, rule); } return [value]; } /** * Convert object to array. */ function objectToArray(value, prop, rule, isFallback, isInArray) { if (!(propObj[prop] || customPropObj[prop])) return []; var result = []; // Check if exists any non-standard property if (customPropObj[prop]) { // eslint-disable-next-line no-param-reassign value = customPropsToStyle(value, rule, customPropObj[prop], isFallback); } // Pass throught all standart props if (Object.keys(value).length) { for (var baseProp in propObj[prop]) { if (value[baseProp]) { if (Array.isArray(value[baseProp])) { result.push(propArrayInObj[baseProp] === null ? value[baseProp] : value[baseProp].join(' ')); } else result.push(value[baseProp]); continue; } // Add default value from props config. if (propObj[prop][baseProp] != null) { result.push(propObj[prop][baseProp]); } } } if (!result.length || isInArray) return result; return [result]; } /** * Convert custom properties values to styles adding them to rule directly */ function customPropsToStyle(value, rule, customProps, isFallback) { for (var prop in customProps) { var propName = customProps[prop]; // If current property doesn't exist already in rule - add new one if (typeof value[prop] !== 'undefined' && (isFallback || !rule.prop(propName))) { var _styleDetector; var appendedValue = styleDetector((_styleDetector = {}, _styleDetector[propName] = value[prop], _styleDetector), rule)[propName]; // Add style directly in rule if (isFallback) rule.style.fallbacks[propName] = appendedValue;else rule.style[propName] = appendedValue; } // Delete converted property to avoid double converting delete value[prop]; } return value; } /** * Detect if a style needs to be converted. */ function styleDetector(style, rule, isFallback) { for (var prop in style) { var value = style[prop]; if (Array.isArray(value)) { // Check double arrays to avoid recursion. if (!Array.isArray(value[0])) { if (prop === 'fallbacks') { for (var index = 0; index < style.fallbacks.length; index++) { style.fallbacks[index] = styleDetector(style.fallbacks[index], rule, true); } continue; } style[prop] = processArray(value, prop, propArray, rule); // Avoid creating properties with empty values if (!style[prop].length) delete style[prop]; } } else if (typeof value === 'object') { if (prop === 'fallbacks') { style.fallbacks = styleDetector(style.fallbacks, rule, true); continue; } style[prop] = objectToArray(value, prop, rule, isFallback); // Avoid creating properties with empty values if (!style[prop].length) delete style[prop]; } // Maybe a computed value resulting in an empty string else if (style[prop] === '') delete style[prop]; } return style; } /** * Adds possibility to write expanded styles. */ function jssExpand() { function onProcessStyle(style, rule) { if (!style || rule.type !== 'style') return style; if (Array.isArray(style)) { // Pass rules one by one and reformat them for (var index = 0; index < style.length; index++) { style[index] = styleDetector(style[index], rule); } return style; } return styleDetector(style, rule); } return { onProcessStyle: onProcessStyle }; } /* harmony default export */ __webpack_exports__["default"] = (jssExpand); /***/ }), /***/ "./node_modules/jss-plugin-extend/dist/jss-plugin-extend.esm.js": /*!**********************************************************************!*\ !*** ./node_modules/jss-plugin-extend/dist/jss-plugin-extend.esm.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js"); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); var isObject = function isObject(obj) { return obj && typeof obj === 'object' && !Array.isArray(obj); }; var valueNs = "extendCurrValue" + Date.now(); function mergeExtend(style, rule, sheet, newStyle) { var extendType = typeof style.extend; // Extend using a rule name. if (extendType === 'string') { if (!sheet) return; var refRule = sheet.getRule(style.extend); if (!refRule) return; if (refRule === rule) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_1__["default"])(false, "[JSS] A rule tries to extend itself \n" + rule.toString()) : undefined; return; } var parent = refRule.options.parent; if (parent) { var originalStyle = parent.rules.raw[style.extend]; extend(originalStyle, rule, sheet, newStyle); } return; } // Extend using an array. if (Array.isArray(style.extend)) { for (var index = 0; index < style.extend.length; index++) { var singleExtend = style.extend[index]; var singleStyle = typeof singleExtend === 'string' ? Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, style, { extend: singleExtend }) : style.extend[index]; extend(singleStyle, rule, sheet, newStyle); } return; } // Extend is a style object. for (var prop in style.extend) { if (prop === 'extend') { extend(style.extend.extend, rule, sheet, newStyle); continue; } if (isObject(style.extend[prop])) { if (!(prop in newStyle)) newStyle[prop] = {}; extend(style.extend[prop], rule, sheet, newStyle[prop]); continue; } newStyle[prop] = style.extend[prop]; } } function mergeRest(style, rule, sheet, newStyle) { // Copy base style. for (var prop in style) { if (prop === 'extend') continue; if (isObject(newStyle[prop]) && isObject(style[prop])) { extend(style[prop], rule, sheet, newStyle[prop]); continue; } if (isObject(style[prop])) { newStyle[prop] = extend(style[prop], rule, sheet); continue; } newStyle[prop] = style[prop]; } } /** * Recursively extend styles. */ function extend(style, rule, sheet, newStyle) { if (newStyle === void 0) { newStyle = {}; } mergeExtend(style, rule, sheet, newStyle); mergeRest(style, rule, sheet, newStyle); return newStyle; } /** * Handle `extend` property. * * @param {Rule} rule * @api public */ function jssExtend() { function onProcessStyle(style, rule, sheet) { if ('extend' in style) return extend(style, rule, sheet); return style; } function onChangeValue(value, prop, rule) { if (prop !== 'extend') return value; // Value is empty, remove properties set previously. if (value == null || value === false) { // $FlowFixMe[prop-missing] for (var key in rule[valueNs]) { rule.prop(key, null); } // $FlowFixMe[prop-missing] Flow complains because there is no indexer property in StyleRule rule[valueNs] = null; return null; } if (typeof value === 'object') { // $FlowFixMe[invalid-in-rhs] This will be an object for (var _key in value) { // $FlowFixMe[incompatible-use] This will be an object rule.prop(_key, value[_key]); } // $FlowFixMe[prop-missing] Flow complains because there is no indexer property in StyleRule rule[valueNs] = value; } // Make sure we don't set the value in the core. return null; } return { onProcessStyle: onProcessStyle, onChangeValue: onChangeValue }; } /* harmony default export */ __webpack_exports__["default"] = (jssExtend); /***/ }), /***/ "./node_modules/jss-plugin-global/dist/jss-plugin-global.esm.js": /*!**********************************************************************!*\ !*** ./node_modules/jss-plugin-global/dist/jss-plugin-global.esm.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js"); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); var at = '@global'; var atPrefix = '@global '; var GlobalContainerRule = /*#__PURE__*/ function () { function GlobalContainerRule(key, styles, options) { this.type = 'global'; this.at = at; this.rules = void 0; this.options = void 0; this.key = void 0; this.isProcessed = false; this.key = key; this.options = options; this.rules = new jss__WEBPACK_IMPORTED_MODULE_1__["RuleList"](Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { parent: this })); for (var selector in styles) { this.rules.add(selector, styles[selector]); } this.rules.process(); } /** * Get a rule. */ var _proto = GlobalContainerRule.prototype; _proto.getRule = function getRule(name) { return this.rules.get(name); } /** * Create and register rule, run plugins. */ ; _proto.addRule = function addRule(name, style, options) { var rule = this.rules.add(name, style, options); if (rule) this.options.jss.plugins.onProcessRule(rule); return rule; } /** * Get index of a rule. */ ; _proto.indexOf = function indexOf(rule) { return this.rules.indexOf(rule); } /** * Generates a CSS string. */ ; _proto.toString = function toString() { return this.rules.toString(); }; return GlobalContainerRule; }(); var GlobalPrefixedRule = /*#__PURE__*/ function () { function GlobalPrefixedRule(key, style, options) { this.type = 'global'; this.at = at; this.options = void 0; this.rule = void 0; this.isProcessed = false; this.key = void 0; this.key = key; this.options = options; var selector = key.substr(atPrefix.length); this.rule = options.jss.createRule(selector, style, Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { parent: this })); } var _proto2 = GlobalPrefixedRule.prototype; _proto2.toString = function toString(options) { return this.rule ? this.rule.toString(options) : ''; }; return GlobalPrefixedRule; }(); var separatorRegExp = /\s*,\s*/g; function addScope(selector, scope) { var parts = selector.split(separatorRegExp); var scoped = ''; for (var i = 0; i < parts.length; i++) { scoped += scope + " " + parts[i].trim(); if (parts[i + 1]) scoped += ', '; } return scoped; } function handleNestedGlobalContainerRule(rule, sheet) { var options = rule.options, style = rule.style; var rules = style ? style[at] : null; if (!rules) return; for (var name in rules) { sheet.addRule(name, rules[name], Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { selector: addScope(name, rule.selector) })); } delete style[at]; } function handlePrefixedGlobalRule(rule, sheet) { var options = rule.options, style = rule.style; for (var prop in style) { if (prop[0] !== '@' || prop.substr(0, at.length) !== at) continue; var selector = addScope(prop.substr(at.length), rule.selector); sheet.addRule(selector, style[prop], Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { selector: selector })); delete style[prop]; } } /** * Convert nested rules to separate, remove them from original styles. * * @param {Rule} rule * @api public */ function jssGlobal() { function onCreateRule(name, styles, options) { if (!name) return null; if (name === at) { return new GlobalContainerRule(name, styles, options); } if (name[0] === '@' && name.substr(0, atPrefix.length) === atPrefix) { return new GlobalPrefixedRule(name, styles, options); } var parent = options.parent; if (parent) { if (parent.type === 'global' || parent.options.parent && parent.options.parent.type === 'global') { options.scoped = false; } } if (options.scoped === false) { options.selector = name; } return null; } function onProcessRule(rule, sheet) { if (rule.type !== 'style' || !sheet) return; handleNestedGlobalContainerRule(rule, sheet); handlePrefixedGlobalRule(rule, sheet); } return { onCreateRule: onCreateRule, onProcessRule: onProcessRule }; } /* harmony default export */ __webpack_exports__["default"] = (jssGlobal); /***/ }), /***/ "./node_modules/jss-plugin-nested/dist/jss-plugin-nested.esm.js": /*!**********************************************************************!*\ !*** ./node_modules/jss-plugin-nested/dist/jss-plugin-nested.esm.js ***! \**********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js"); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); var separatorRegExp = /\s*,\s*/g; var parentRegExp = /&/g; var refRegExp = /\$([\w-]+)/g; /** * Convert nested rules to separate, remove them from original styles. * * @param {Rule} rule * @api public */ function jssNested() { // Get a function to be used for $ref replacement. function getReplaceRef(container, sheet) { return function (match, key) { var rule = container.getRule(key) || sheet && sheet.getRule(key); if (rule) { rule = rule; return rule.selector; } true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_1__["default"])(false, "[JSS] Could not find the referenced rule \"" + key + "\" in \"" + (container.options.meta || container.toString()) + "\".") : undefined; return key; }; } function replaceParentRefs(nestedProp, parentProp) { var parentSelectors = parentProp.split(separatorRegExp); var nestedSelectors = nestedProp.split(separatorRegExp); var result = ''; for (var i = 0; i < parentSelectors.length; i++) { var parent = parentSelectors[i]; for (var j = 0; j < nestedSelectors.length; j++) { var nested = nestedSelectors[j]; if (result) result += ', '; // Replace all & by the parent or prefix & with the parent. result += nested.indexOf('&') !== -1 ? nested.replace(parentRegExp, parent) : parent + " " + nested; } } return result; } function getOptions(rule, container, prevOptions) { // Options has been already created, now we only increase index. if (prevOptions) return Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, prevOptions, { index: prevOptions.index + 1 // $FlowFixMe[prop-missing] }); var nestingLevel = rule.options.nestingLevel; nestingLevel = nestingLevel === undefined ? 1 : nestingLevel + 1; var options = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, rule.options, { nestingLevel: nestingLevel, index: container.indexOf(rule) + 1 // We don't need the parent name to be set options for chlid. }); delete options.name; return options; } function onProcessStyle(style, rule, sheet) { if (rule.type !== 'style') return style; var styleRule = rule; var container = styleRule.options.parent; var options; var replaceRef; for (var prop in style) { var isNested = prop.indexOf('&') !== -1; var isNestedConditional = prop[0] === '@'; if (!isNested && !isNestedConditional) continue; options = getOptions(styleRule, container, options); if (isNested) { var selector = replaceParentRefs(prop, styleRule.selector); // Lazily create the ref replacer function just once for // all nested rules within the sheet. if (!replaceRef) replaceRef = getReplaceRef(container, sheet); // Replace all $refs. selector = selector.replace(refRegExp, replaceRef); container.addRule(selector, style[prop], Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { selector: selector })); } else if (isNestedConditional) { // Place conditional right after the parent rule to ensure right ordering. container.addRule(prop, {}, options) // Flow expects more options but they aren't required // And flow doesn't know this will always be a StyleRule which has the addRule method // $FlowFixMe[incompatible-use] // $FlowFixMe[prop-missing] .addRule(styleRule.key, style[prop], { selector: styleRule.selector }); } delete style[prop]; } return style; } return { onProcessStyle: onProcessStyle }; } /* harmony default export */ __webpack_exports__["default"] = (jssNested); /***/ }), /***/ "./node_modules/jss-plugin-props-sort/dist/jss-plugin-props-sort.esm.js": /*!******************************************************************************!*\ !*** ./node_modules/jss-plugin-props-sort/dist/jss-plugin-props-sort.esm.js ***! \******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /** * Sort props by length. */ function jssPropsSort() { var sort = function sort(prop0, prop1) { if (prop0.length === prop1.length) { return prop0 > prop1 ? 1 : -1; } return prop0.length - prop1.length; }; return { onProcessStyle: function onProcessStyle(style, rule) { if (rule.type !== 'style') return style; var newStyle = {}; var props = Object.keys(style).sort(sort); for (var i = 0; i < props.length; i++) { newStyle[props[i]] = style[props[i]]; } return newStyle; } }; } /* harmony default export */ __webpack_exports__["default"] = (jssPropsSort); /***/ }), /***/ "./node_modules/jss-plugin-rule-value-function/dist/jss-plugin-rule-value-function.esm.js": /*!************************************************************************************************!*\ !*** ./node_modules/jss-plugin-rule-value-function/dist/jss-plugin-rule-value-function.esm.js ***! \************************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); var now = Date.now(); var fnValuesNs = "fnValues" + now; var fnRuleNs = "fnStyle" + ++now; var functionPlugin = function functionPlugin() { return { onCreateRule: function onCreateRule(name, decl, options) { if (typeof decl !== 'function') return null; var rule = Object(jss__WEBPACK_IMPORTED_MODULE_1__["createRule"])(name, {}, options); rule[fnRuleNs] = decl; return rule; }, onProcessStyle: function onProcessStyle(style, rule) { // We need to extract function values from the declaration, so that we can keep core unaware of them. // We need to do that only once. // We don't need to extract functions on each style update, since this can happen only once. // We don't support function values inside of function rules. if (fnValuesNs in rule || fnRuleNs in rule) return style; var fnValues = {}; for (var prop in style) { var value = style[prop]; if (typeof value !== 'function') continue; delete style[prop]; fnValues[prop] = value; } // $FlowFixMe[prop-missing] rule[fnValuesNs] = fnValues; return style; }, onUpdate: function onUpdate(data, rule, sheet, options) { var styleRule = rule; // $FlowFixMe[prop-missing] var fnRule = styleRule[fnRuleNs]; // If we have a style function, the entire rule is dynamic and style object // will be returned from that function. if (fnRule) { // Empty object will remove all currently defined props // in case function rule returns a falsy value. styleRule.style = fnRule(data) || {}; if (true) { for (var prop in styleRule.style) { if (typeof styleRule.style[prop] === 'function') { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_0__["default"])(false, '[JSS] Function values inside function rules are not supported.') : undefined; break; } } } } // $FlowFixMe[prop-missing] var fnValues = styleRule[fnValuesNs]; // If we have a fn values map, it is a rule with function values. if (fnValues) { for (var _prop in fnValues) { styleRule.prop(_prop, fnValues[_prop](data), options); } } } }; }; /* harmony default export */ __webpack_exports__["default"] = (functionPlugin); /***/ }), /***/ "./node_modules/jss-plugin-rule-value-observable/dist/jss-plugin-rule-value-observable.esm.js": /*!****************************************************************************************************!*\ !*** ./node_modules/jss-plugin-rule-value-observable/dist/jss-plugin-rule-value-observable.esm.js ***! \****************************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! symbol-observable */ "./node_modules/symbol-observable/es/index.js"); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); var isObservable = function isObservable(value) { return value && value[symbol_observable__WEBPACK_IMPORTED_MODULE_0__["default"]] && value === value[symbol_observable__WEBPACK_IMPORTED_MODULE_0__["default"]](); }; var observablePlugin = function observablePlugin(updateOptions) { return { onCreateRule: function onCreateRule(name, decl, options) { if (!isObservable(decl)) return null; // Cast `decl` to `Observable`, since it passed the type guard. var style$ = decl; var rule = Object(jss__WEBPACK_IMPORTED_MODULE_1__["createRule"])(name, {}, options); // TODO // Call `stream.subscribe()` returns a subscription, which should be explicitly // unsubscribed from when we know this sheet is no longer needed. style$.subscribe(function (style) { for (var prop in style) { rule.prop(prop, style[prop], updateOptions); } }); return rule; }, onProcessRule: function onProcessRule(rule) { if (rule && rule.type !== 'style') return; var styleRule = rule; var style = styleRule.style; var _loop = function _loop(prop) { var value = style[prop]; if (!isObservable(value)) return "continue"; delete style[prop]; value.subscribe({ next: function next(nextValue) { styleRule.prop(prop, nextValue, updateOptions); } }); }; for (var prop in style) { var _ret = _loop(prop); if (_ret === "continue") continue; } } }; }; /* harmony default export */ __webpack_exports__["default"] = (observablePlugin); /***/ }), /***/ "./node_modules/jss-plugin-template/dist/jss-plugin-template.esm.js": /*!**************************************************************************!*\ !*** ./node_modules/jss-plugin-template/dist/jss-plugin-template.esm.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); var semiWithNl = /;\n/; /** * Naive CSS parser. * - Supports only rule body (no selectors) * - Requires semicolon and new line after the value (except of last line) * - No nested rules support */ var parse = function parse(cssText) { var style = {}; var split = cssText.split(semiWithNl); for (var i = 0; i < split.length; i++) { var decl = (split[i] || '').trim(); if (!decl) continue; var colonIndex = decl.indexOf(':'); if (colonIndex === -1) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_0__["default"])(false, "[JSS] Malformed CSS string \"" + decl + "\"") : undefined; continue; } var prop = decl.substr(0, colonIndex).trim(); var value = decl.substr(colonIndex + 1).trim(); style[prop] = value; } return style; }; var onProcessRule = function onProcessRule(rule) { if (typeof rule.style === 'string') { // $FlowFixMe[prop-missing] We can safely assume that rule has the style property rule.style = parse(rule.style); } }; function templatePlugin() { return { onProcessRule: onProcessRule }; } /* harmony default export */ __webpack_exports__["default"] = (templatePlugin); /***/ }), /***/ "./node_modules/jss-plugin-vendor-prefixer/dist/jss-plugin-vendor-prefixer.esm.js": /*!****************************************************************************************!*\ !*** ./node_modules/jss-plugin-vendor-prefixer/dist/jss-plugin-vendor-prefixer.esm.js ***! \****************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var css_vendor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! css-vendor */ "./node_modules/css-vendor/dist/css-vendor.esm.js"); /* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss */ "./node_modules/jss/dist/jss.esm.js"); /** * Add vendor prefix to a property name when needed. * * @api public */ function jssVendorPrefixer() { function onProcessRule(rule) { if (rule.type === 'keyframes') { var atRule = rule; atRule.at = Object(css_vendor__WEBPACK_IMPORTED_MODULE_0__["supportedKeyframes"])(atRule.at); } } function prefixStyle(style) { for (var prop in style) { var value = style[prop]; if (prop === 'fallbacks' && Array.isArray(value)) { style[prop] = value.map(prefixStyle); continue; } var changeProp = false; var supportedProp = Object(css_vendor__WEBPACK_IMPORTED_MODULE_0__["supportedProperty"])(prop); if (supportedProp && supportedProp !== prop) changeProp = true; var changeValue = false; var supportedValue$1 = Object(css_vendor__WEBPACK_IMPORTED_MODULE_0__["supportedValue"])(supportedProp, Object(jss__WEBPACK_IMPORTED_MODULE_1__["toCssValue"])(value)); if (supportedValue$1 && supportedValue$1 !== value) changeValue = true; if (changeProp || changeValue) { if (changeProp) delete style[prop]; style[supportedProp || prop] = supportedValue$1 || value; } } return style; } function onProcessStyle(style, rule) { if (rule.type !== 'style') return style; return prefixStyle(style); } function onChangeValue(value, prop) { return Object(css_vendor__WEBPACK_IMPORTED_MODULE_0__["supportedValue"])(prop, Object(jss__WEBPACK_IMPORTED_MODULE_1__["toCssValue"])(value)) || value; } return { onProcessRule: onProcessRule, onProcessStyle: onProcessStyle, onChangeValue: onChangeValue }; } /* harmony default export */ __webpack_exports__["default"] = (jssVendorPrefixer); /***/ }), /***/ "./node_modules/jss-preset-default/dist/jss-preset-default.esm.js": /*!************************************************************************!*\ !*** ./node_modules/jss-preset-default/dist/jss-preset-default.esm.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var jss_plugin_rule_value_function__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jss-plugin-rule-value-function */ "./node_modules/jss-plugin-rule-value-function/dist/jss-plugin-rule-value-function.esm.js"); /* harmony import */ var jss_plugin_rule_value_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss-plugin-rule-value-observable */ "./node_modules/jss-plugin-rule-value-observable/dist/jss-plugin-rule-value-observable.esm.js"); /* harmony import */ var jss_plugin_template__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jss-plugin-template */ "./node_modules/jss-plugin-template/dist/jss-plugin-template.esm.js"); /* harmony import */ var jss_plugin_global__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! jss-plugin-global */ "./node_modules/jss-plugin-global/dist/jss-plugin-global.esm.js"); /* harmony import */ var jss_plugin_extend__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! jss-plugin-extend */ "./node_modules/jss-plugin-extend/dist/jss-plugin-extend.esm.js"); /* harmony import */ var jss_plugin_nested__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! jss-plugin-nested */ "./node_modules/jss-plugin-nested/dist/jss-plugin-nested.esm.js"); /* harmony import */ var jss_plugin_compose__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! jss-plugin-compose */ "./node_modules/jss-plugin-compose/dist/jss-plugin-compose.esm.js"); /* harmony import */ var jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! jss-plugin-camel-case */ "./node_modules/jss-plugin-camel-case/dist/jss-plugin-camel-case.esm.js"); /* harmony import */ var jss_plugin_default_unit__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! jss-plugin-default-unit */ "./node_modules/jss-plugin-default-unit/dist/jss-plugin-default-unit.esm.js"); /* harmony import */ var jss_plugin_expand__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! jss-plugin-expand */ "./node_modules/jss-plugin-expand/dist/jss-plugin-expand.esm.js"); /* harmony import */ var jss_plugin_vendor_prefixer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! jss-plugin-vendor-prefixer */ "./node_modules/jss-plugin-vendor-prefixer/dist/jss-plugin-vendor-prefixer.esm.js"); /* harmony import */ var jss_plugin_props_sort__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! jss-plugin-props-sort */ "./node_modules/jss-plugin-props-sort/dist/jss-plugin-props-sort.esm.js"); var create = function create(options) { if (options === void 0) { options = {}; } return { plugins: [Object(jss_plugin_rule_value_function__WEBPACK_IMPORTED_MODULE_0__["default"])(), Object(jss_plugin_rule_value_observable__WEBPACK_IMPORTED_MODULE_1__["default"])(options.observable), Object(jss_plugin_template__WEBPACK_IMPORTED_MODULE_2__["default"])(), Object(jss_plugin_global__WEBPACK_IMPORTED_MODULE_3__["default"])(), Object(jss_plugin_extend__WEBPACK_IMPORTED_MODULE_4__["default"])(), Object(jss_plugin_nested__WEBPACK_IMPORTED_MODULE_5__["default"])(), Object(jss_plugin_compose__WEBPACK_IMPORTED_MODULE_6__["default"])(), Object(jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_7__["default"])(), Object(jss_plugin_default_unit__WEBPACK_IMPORTED_MODULE_8__["default"])(options.defaultUnit), Object(jss_plugin_expand__WEBPACK_IMPORTED_MODULE_9__["default"])(), Object(jss_plugin_vendor_prefixer__WEBPACK_IMPORTED_MODULE_10__["default"])(), Object(jss_plugin_props_sort__WEBPACK_IMPORTED_MODULE_11__["default"])()] }; }; /* harmony default export */ __webpack_exports__["default"] = (create); /***/ }), /***/ "./node_modules/jss/dist/jss.esm.js": /*!******************************************!*\ !*** ./node_modules/jss/dist/jss.esm.js ***! \******************************************/ /*! exports provided: default, RuleList, SheetsManager, SheetsRegistry, create, createGenerateId, createRule, getDynamicStyles, hasCSSTOMSupport, sheets, toCssValue */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RuleList", function() { return RuleList; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SheetsManager", function() { return SheetsManager; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SheetsRegistry", function() { return SheetsRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "create", function() { return create; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createGenerateId", function() { return createGenerateId; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createRule", function() { return createRule; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDynamicStyles", function() { return getDynamicStyles; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasCSSTOMSupport", function() { return hasCSSTOMSupport; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sheets", function() { return registry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toCssValue", function() { return toCssValue; }); /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ "./node_modules/@babel/runtime/helpers/esm/extends.js"); /* harmony import */ var is_in_browser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! is-in-browser */ "./node_modules/is-in-browser/dist/module.js"); /* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tiny-warning */ "./node_modules/tiny-warning/dist/tiny-warning.esm.js"); /* harmony import */ var _babel_runtime_helpers_esm_createClass__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/esm/createClass */ "./node_modules/@babel/runtime/helpers/esm/createClass.js"); /* harmony import */ var _babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/esm/inheritsLoose */ "./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js"); /* harmony import */ var _babel_runtime_helpers_esm_assertThisInitialized__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @babel/runtime/helpers/esm/assertThisInitialized */ "./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js"); /* harmony import */ var _babel_runtime_helpers_esm_objectWithoutPropertiesLoose__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @babel/runtime/helpers/esm/objectWithoutPropertiesLoose */ "./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js"); var plainObjectConstrurctor = {}.constructor; function cloneStyle(style) { if (style == null || typeof style !== 'object') return style; if (Array.isArray(style)) return style.map(cloneStyle); if (style.constructor !== plainObjectConstrurctor) return style; var newStyle = {}; for (var name in style) { newStyle[name] = cloneStyle(style[name]); } return newStyle; } /** * Create a rule instance. */ function createRule(name, decl, options) { if (name === void 0) { name = 'unnamed'; } var jss = options.jss; var declCopy = cloneStyle(decl); var rule = jss.plugins.onCreateRule(name, declCopy, options); if (rule) return rule; // It is an at-rule and it has no instance. if (name[0] === '@') { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] Unknown rule " + name) : undefined; } return null; } var join = function join(value, by) { var result = ''; for (var i = 0; i < value.length; i++) { // Remove !important from the value, it will be readded later. if (value[i] === '!important') break; if (result) result += by; result += value[i]; } return result; }; /** * Converts array values to string. * * `margin: [['5px', '10px']]` > `margin: 5px 10px;` * `border: ['1px', '2px']` > `border: 1px, 2px;` * `margin: [['5px', '10px'], '!important']` > `margin: 5px 10px !important;` * `color: ['red', !important]` > `color: red !important;` */ var toCssValue = function toCssValue(value, ignoreImportant) { if (ignoreImportant === void 0) { ignoreImportant = false; } if (!Array.isArray(value)) return value; var cssValue = ''; // Support space separated values via `[['5px', '10px']]`. if (Array.isArray(value[0])) { for (var i = 0; i < value.length; i++) { if (value[i] === '!important') break; if (cssValue) cssValue += ', '; cssValue += join(value[i], ' '); } } else cssValue = join(value, ', '); // Add !important, because it was ignored. if (!ignoreImportant && value[value.length - 1] === '!important') { cssValue += ' !important'; } return cssValue; }; /** * Indent a string. * http://jsperf.com/array-join-vs-for */ function indentStr(str, indent) { var result = ''; for (var index = 0; index < indent; index++) { result += ' '; } return result + str; } /** * Converts a Rule to CSS string. */ function toCss(selector, style, options) { if (options === void 0) { options = {}; } var result = ''; if (!style) return result; var _options = options, _options$indent = _options.indent, indent = _options$indent === void 0 ? 0 : _options$indent; var fallbacks = style.fallbacks; if (selector) indent++; // Apply fallbacks first. if (fallbacks) { // Array syntax {fallbacks: [{prop: value}]} if (Array.isArray(fallbacks)) { for (var index = 0; index < fallbacks.length; index++) { var fallback = fallbacks[index]; for (var prop in fallback) { var value = fallback[prop]; if (value != null) { if (result) result += '\n'; result += "" + indentStr(prop + ": " + toCssValue(value) + ";", indent); } } } } else { // Object syntax {fallbacks: {prop: value}} for (var _prop in fallbacks) { var _value = fallbacks[_prop]; if (_value != null) { if (result) result += '\n'; result += "" + indentStr(_prop + ": " + toCssValue(_value) + ";", indent); } } } } for (var _prop2 in style) { var _value2 = style[_prop2]; if (_value2 != null && _prop2 !== 'fallbacks') { if (result) result += '\n'; result += "" + indentStr(_prop2 + ": " + toCssValue(_value2) + ";", indent); } } // Allow empty style in this case, because properties will be added dynamically. if (!result && !options.allowEmpty) return result; // When rule is being stringified before selector was defined. if (!selector) return result; indent--; if (result) result = "\n" + result + "\n"; return indentStr(selector + " {" + result, indent) + indentStr('}', indent); } var escapeRegex = /([[\].#*$><+~=|^:(),"'`\s])/g; var nativeEscape = typeof CSS !== 'undefined' && CSS.escape; var escape = (function (str) { return nativeEscape ? nativeEscape(str) : str.replace(escapeRegex, '\\$1'); }); var BaseStyleRule = /*#__PURE__*/ function () { function BaseStyleRule(key, style, options) { this.type = 'style'; this.key = void 0; this.isProcessed = false; this.style = void 0; this.renderer = void 0; this.renderable = void 0; this.options = void 0; var sheet = options.sheet, Renderer = options.Renderer; this.key = key; this.options = options; this.style = style; if (sheet) this.renderer = sheet.renderer;else if (Renderer) this.renderer = new Renderer(); } /** * Get or set a style property. */ var _proto = BaseStyleRule.prototype; _proto.prop = function prop(name, value, options) { // It's a getter. if (value === undefined) return this.style[name]; // Don't do anything if the value has not changed. var force = options ? options.force : false; if (!force && this.style[name] === value) return this; var newValue = value; if (!options || options.process !== false) { newValue = this.options.jss.plugins.onChangeValue(value, name, this); } var isEmpty = newValue == null || newValue === false; var isDefined = name in this.style; // Value is empty and wasn't defined before. if (isEmpty && !isDefined && !force) return this; // We are going to remove this value. var remove = isEmpty && isDefined; if (remove) delete this.style[name];else this.style[name] = newValue; // Renderable is defined if StyleSheet option `link` is true. if (this.renderable && this.renderer) { if (remove) this.renderer.removeProperty(this.renderable, name);else this.renderer.setProperty(this.renderable, name, newValue); return this; } var sheet = this.options.sheet; if (sheet && sheet.attached) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, '[JSS] Rule is not linked. Missing sheet option "link: true".') : undefined; } return this; }; return BaseStyleRule; }(); var StyleRule = /*#__PURE__*/ function (_BaseStyleRule) { Object(_babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_4__["default"])(StyleRule, _BaseStyleRule); function StyleRule(key, style, options) { var _this; _this = _BaseStyleRule.call(this, key, style, options) || this; _this.selectorText = void 0; _this.id = void 0; _this.renderable = void 0; var selector = options.selector, scoped = options.scoped, sheet = options.sheet, generateId = options.generateId; if (selector) { _this.selectorText = selector; } else if (scoped !== false) { _this.id = generateId(Object(_babel_runtime_helpers_esm_assertThisInitialized__WEBPACK_IMPORTED_MODULE_5__["default"])(Object(_babel_runtime_helpers_esm_assertThisInitialized__WEBPACK_IMPORTED_MODULE_5__["default"])(_this)), sheet); _this.selectorText = "." + escape(_this.id); } return _this; } /** * Set selector string. * Attention: use this with caution. Most browsers didn't implement * selectorText setter, so this may result in rerendering of entire Style Sheet. */ var _proto2 = StyleRule.prototype; /** * Apply rule to an element inline. */ _proto2.applyTo = function applyTo(renderable) { var renderer = this.renderer; if (renderer) { var json = this.toJSON(); for (var prop in json) { renderer.setProperty(renderable, prop, json[prop]); } } return this; } /** * Returns JSON representation of the rule. * Fallbacks are not supported. * Useful for inline styles. */ ; _proto2.toJSON = function toJSON() { var json = {}; for (var prop in this.style) { var value = this.style[prop]; if (typeof value !== 'object') json[prop] = value;else if (Array.isArray(value)) json[prop] = toCssValue(value); } return json; } /** * Generates a CSS string. */ ; _proto2.toString = function toString(options) { var sheet = this.options.sheet; var link = sheet ? sheet.options.link : false; var opts = link ? Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { allowEmpty: true }) : options; return toCss(this.selectorText, this.style, opts); }; Object(_babel_runtime_helpers_esm_createClass__WEBPACK_IMPORTED_MODULE_3__["default"])(StyleRule, [{ key: "selector", set: function set(selector) { if (selector === this.selectorText) return; this.selectorText = selector; var renderer = this.renderer, renderable = this.renderable; if (!renderable || !renderer) return; var hasChanged = renderer.setSelector(renderable, selector); // If selector setter is not implemented, rerender the rule. if (!hasChanged) { renderer.replaceRule(renderable, this); } } /** * Get selector string. */ , get: function get() { return this.selectorText; } }]); return StyleRule; }(BaseStyleRule); var pluginStyleRule = { onCreateRule: function onCreateRule(name, style, options) { if (name[0] === '@' || options.parent && options.parent.type === 'keyframes') { return null; } return new StyleRule(name, style, options); } }; var defaultToStringOptions = { indent: 1, children: true }; var atRegExp = /@([\w-]+)/; /** * Conditional rule for @media, @supports */ var ConditionalRule = /*#__PURE__*/ function () { function ConditionalRule(key, styles, options) { this.type = 'conditional'; this.at = void 0; this.key = void 0; this.query = void 0; this.rules = void 0; this.options = void 0; this.isProcessed = false; this.renderable = void 0; this.key = key; var atMatch = key.match(atRegExp); this.at = atMatch ? atMatch[1] : 'unknown'; // Key might contain a unique suffix in case the `name` passed by user was duplicate. this.query = options.name || "@" + this.at; this.options = options; this.rules = new RuleList(Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { parent: this })); for (var name in styles) { this.rules.add(name, styles[name]); } this.rules.process(); } /** * Get a rule. */ var _proto = ConditionalRule.prototype; _proto.getRule = function getRule(name) { return this.rules.get(name); } /** * Get index of a rule. */ ; _proto.indexOf = function indexOf(rule) { return this.rules.indexOf(rule); } /** * Create and register rule, run plugins. */ ; _proto.addRule = function addRule(name, style, options) { var rule = this.rules.add(name, style, options); if (!rule) return null; this.options.jss.plugins.onProcessRule(rule); return rule; } /** * Generates a CSS string. */ ; _proto.toString = function toString(options) { if (options === void 0) { options = defaultToStringOptions; } if (options.indent == null) options.indent = defaultToStringOptions.indent; if (options.children == null) options.children = defaultToStringOptions.children; if (options.children === false) { return this.query + " {}"; } var children = this.rules.toString(options); return children ? this.query + " {\n" + children + "\n}" : ''; }; return ConditionalRule; }(); var keyRegExp = /@media|@supports\s+/; var pluginConditionalRule = { onCreateRule: function onCreateRule(key, styles, options) { return keyRegExp.test(key) ? new ConditionalRule(key, styles, options) : null; } }; var defaultToStringOptions$1 = { indent: 1, children: true }; var nameRegExp = /@keyframes\s+([\w-]+)/; /** * Rule for @keyframes */ var KeyframesRule = /*#__PURE__*/ function () { function KeyframesRule(key, frames, options) { this.type = 'keyframes'; this.at = '@keyframes'; this.key = void 0; this.name = void 0; this.id = void 0; this.rules = void 0; this.options = void 0; this.isProcessed = false; this.renderable = void 0; var nameMatch = key.match(nameRegExp); if (nameMatch && nameMatch[1]) { this.name = nameMatch[1]; } else { this.name = 'noname'; true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] Bad keyframes name " + key) : undefined; } this.key = this.type + "-" + this.name; this.options = options; var scoped = options.scoped, sheet = options.sheet, generateId = options.generateId; this.id = scoped === false ? this.name : escape(generateId(this, sheet)); this.rules = new RuleList(Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { parent: this })); for (var name in frames) { this.rules.add(name, frames[name], Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { parent: this })); } this.rules.process(); } /** * Generates a CSS string. */ var _proto = KeyframesRule.prototype; _proto.toString = function toString(options) { if (options === void 0) { options = defaultToStringOptions$1; } if (options.indent == null) options.indent = defaultToStringOptions$1.indent; if (options.children == null) options.children = defaultToStringOptions$1.children; if (options.children === false) { return this.at + " " + this.id + " {}"; } var children = this.rules.toString(options); if (children) children = "\n" + children + "\n"; return this.at + " " + this.id + " {" + children + "}"; }; return KeyframesRule; }(); var keyRegExp$1 = /@keyframes\s+/; var refRegExp = /\$([\w-]+)/g; var findReferencedKeyframe = function findReferencedKeyframe(val, keyframes) { if (typeof val === 'string') { return val.replace(refRegExp, function (match, name) { if (name in keyframes) { return keyframes[name]; } true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] Referenced keyframes rule \"" + name + "\" is not defined.") : undefined; return match; }); } return val; }; /** * Replace the reference for a animation name. */ var replaceRef = function replaceRef(style, prop, keyframes) { var value = style[prop]; var refKeyframe = findReferencedKeyframe(value, keyframes); if (refKeyframe !== value) { style[prop] = refKeyframe; } }; var plugin = { onCreateRule: function onCreateRule(key, frames, options) { return typeof key === 'string' && keyRegExp$1.test(key) ? new KeyframesRule(key, frames, options) : null; }, // Animation name ref replacer. onProcessStyle: function onProcessStyle(style, rule, sheet) { if (rule.type !== 'style' || !sheet) return style; if ('animation-name' in style) replaceRef(style, 'animation-name', sheet.keyframes); if ('animation' in style) replaceRef(style, 'animation', sheet.keyframes); return style; }, onChangeValue: function onChangeValue(val, prop, rule) { var sheet = rule.options.sheet; if (!sheet) { return val; } switch (prop) { case 'animation': return findReferencedKeyframe(val, sheet.keyframes); case 'animation-name': return findReferencedKeyframe(val, sheet.keyframes); default: return val; } } }; var KeyframeRule = /*#__PURE__*/ function (_BaseStyleRule) { Object(_babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_4__["default"])(KeyframeRule, _BaseStyleRule); function KeyframeRule() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _BaseStyleRule.call.apply(_BaseStyleRule, [this].concat(args)) || this; _this.renderable = void 0; return _this; } var _proto = KeyframeRule.prototype; /** * Generates a CSS string. */ _proto.toString = function toString(options) { var sheet = this.options.sheet; var link = sheet ? sheet.options.link : false; var opts = link ? Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { allowEmpty: true }) : options; return toCss(this.key, this.style, opts); }; return KeyframeRule; }(BaseStyleRule); var pluginKeyframeRule = { onCreateRule: function onCreateRule(key, style, options) { if (options.parent && options.parent.type === 'keyframes') { return new KeyframeRule(key, style, options); } return null; } }; var FontFaceRule = /*#__PURE__*/ function () { function FontFaceRule(key, style, options) { this.type = 'font-face'; this.at = '@font-face'; this.key = void 0; this.style = void 0; this.options = void 0; this.isProcessed = false; this.renderable = void 0; this.key = key; this.style = style; this.options = options; } /** * Generates a CSS string. */ var _proto = FontFaceRule.prototype; _proto.toString = function toString(options) { if (Array.isArray(this.style)) { var str = ''; for (var index = 0; index < this.style.length; index++) { str += toCss(this.at, this.style[index]); if (this.style[index + 1]) str += '\n'; } return str; } return toCss(this.at, this.style, options); }; return FontFaceRule; }(); var keyRegExp$2 = /@font-face/; var pluginFontFaceRule = { onCreateRule: function onCreateRule(key, style, options) { return keyRegExp$2.test(key) ? new FontFaceRule(key, style, options) : null; } }; var ViewportRule = /*#__PURE__*/ function () { function ViewportRule(key, style, options) { this.type = 'viewport'; this.at = '@viewport'; this.key = void 0; this.style = void 0; this.options = void 0; this.isProcessed = false; this.renderable = void 0; this.key = key; this.style = style; this.options = options; } /** * Generates a CSS string. */ var _proto = ViewportRule.prototype; _proto.toString = function toString(options) { return toCss(this.key, this.style, options); }; return ViewportRule; }(); var pluginViewportRule = { onCreateRule: function onCreateRule(key, style, options) { return key === '@viewport' || key === '@-ms-viewport' ? new ViewportRule(key, style, options) : null; } }; var SimpleRule = /*#__PURE__*/ function () { function SimpleRule(key, value, options) { this.type = 'simple'; this.key = void 0; this.value = void 0; this.options = void 0; this.isProcessed = false; this.renderable = void 0; this.key = key; this.value = value; this.options = options; } /** * Generates a CSS string. */ // eslint-disable-next-line no-unused-vars var _proto = SimpleRule.prototype; _proto.toString = function toString(options) { if (Array.isArray(this.value)) { var str = ''; for (var index = 0; index < this.value.length; index++) { str += this.key + " " + this.value[index] + ";"; if (this.value[index + 1]) str += '\n'; } return str; } return this.key + " " + this.value + ";"; }; return SimpleRule; }(); var keysMap = { '@charset': true, '@import': true, '@namespace': true }; var pluginSimpleRule = { onCreateRule: function onCreateRule(key, value, options) { return key in keysMap ? new SimpleRule(key, value, options) : null; } }; var plugins = [pluginStyleRule, pluginConditionalRule, plugin, pluginKeyframeRule, pluginFontFaceRule, pluginViewportRule, pluginSimpleRule]; var defaultUpdateOptions = { process: true }; var forceUpdateOptions = { force: true, process: true /** * Contains rules objects and allows adding/removing etc. * Is used for e.g. by `StyleSheet` or `ConditionalRule`. */ }; var RuleList = /*#__PURE__*/ function () { // Rules registry for access by .get() method. // It contains the same rule registered by name and by selector. // Original styles object. // Used to ensure correct rules order. function RuleList(options) { this.map = {}; this.raw = {}; this.index = []; this.counter = 0; this.options = void 0; this.classes = void 0; this.keyframes = void 0; this.options = options; this.classes = options.classes; this.keyframes = options.keyframes; } /** * Create and register rule. * * Will not render after Style Sheet was rendered the first time. */ var _proto = RuleList.prototype; _proto.add = function add(name, decl, ruleOptions) { var _this$options = this.options, parent = _this$options.parent, sheet = _this$options.sheet, jss = _this$options.jss, Renderer = _this$options.Renderer, generateId = _this$options.generateId, scoped = _this$options.scoped; var options = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({ classes: this.classes, parent: parent, sheet: sheet, jss: jss, Renderer: Renderer, generateId: generateId, scoped: scoped, name: name, keyframes: this.keyframes, selector: undefined }, ruleOptions); // When user uses .createStyleSheet(), duplicate names are not possible, but // `sheet.addRule()` opens the door for any duplicate rule name. When this happens // we need to make the key unique within this RuleList instance scope. var key = name; if (name in this.raw) { key = name + "-d" + this.counter++; } // We need to save the original decl before creating the rule // because cache plugin needs to use it as a key to return a cached rule. this.raw[key] = decl; if (key in this.classes) { // E.g. rules inside of @media container options.selector = "." + escape(this.classes[key]); } var rule = createRule(key, decl, options); if (!rule) return null; this.register(rule); var index = options.index === undefined ? this.index.length : options.index; this.index.splice(index, 0, rule); return rule; } /** * Get a rule. */ ; _proto.get = function get(name) { return this.map[name]; } /** * Delete a rule. */ ; _proto.remove = function remove(rule) { this.unregister(rule); delete this.raw[rule.key]; this.index.splice(this.index.indexOf(rule), 1); } /** * Get index of a rule. */ ; _proto.indexOf = function indexOf(rule) { return this.index.indexOf(rule); } /** * Run `onProcessRule()` plugins on every rule. */ ; _proto.process = function process() { var plugins = this.options.jss.plugins; // We need to clone array because if we modify the index somewhere else during a loop // we end up with very hard-to-track-down side effects. this.index.slice(0).forEach(plugins.onProcessRule, plugins); } /** * Register a rule in `.map`, `.classes` and `.keyframes` maps. */ ; _proto.register = function register(rule) { this.map[rule.key] = rule; if (rule instanceof StyleRule) { this.map[rule.selector] = rule; if (rule.id) this.classes[rule.key] = rule.id; } else if (rule instanceof KeyframesRule && this.keyframes) { this.keyframes[rule.name] = rule.id; } } /** * Unregister a rule. */ ; _proto.unregister = function unregister(rule) { delete this.map[rule.key]; if (rule instanceof StyleRule) { delete this.map[rule.selector]; delete this.classes[rule.key]; } else if (rule instanceof KeyframesRule) { delete this.keyframes[rule.name]; } } /** * Update the function values with a new data. */ ; _proto.update = function update() { var name; var data; var options; if (typeof (arguments.length <= 0 ? undefined : arguments[0]) === 'string') { name = arguments.length <= 0 ? undefined : arguments[0]; // $FlowFixMe[invalid-tuple-index] data = arguments.length <= 1 ? undefined : arguments[1]; // $FlowFixMe[invalid-tuple-index] options = arguments.length <= 2 ? undefined : arguments[2]; } else { data = arguments.length <= 0 ? undefined : arguments[0]; // $FlowFixMe[invalid-tuple-index] options = arguments.length <= 1 ? undefined : arguments[1]; name = null; } if (name) { this.updateOne(this.map[name], data, options); } else { for (var index = 0; index < this.index.length; index++) { this.updateOne(this.index[index], data, options); } } } /** * Execute plugins, update rule props. */ ; _proto.updateOne = function updateOne(rule, data, options) { if (options === void 0) { options = defaultUpdateOptions; } var _this$options2 = this.options, plugins = _this$options2.jss.plugins, sheet = _this$options2.sheet; // It is a rules container like for e.g. ConditionalRule. if (rule.rules instanceof RuleList) { rule.rules.update(data, options); return; } var styleRule = rule; var style = styleRule.style; plugins.onUpdate(data, rule, sheet, options); // We rely on a new `style` ref in case it was mutated during onUpdate hook. if (options.process && style && style !== styleRule.style) { // We need to run the plugins in case new `style` relies on syntax plugins. plugins.onProcessStyle(styleRule.style, styleRule, sheet); // Update and add props. for (var prop in styleRule.style) { var nextValue = styleRule.style[prop]; var prevValue = style[prop]; // We need to use `force: true` because `rule.style` has been updated during onUpdate hook, so `rule.prop()` will not update the CSSOM rule. // We do this comparison to avoid unneeded `rule.prop()` calls, since we have the old `style` object here. if (nextValue !== prevValue) { styleRule.prop(prop, nextValue, forceUpdateOptions); } } // Remove props. for (var _prop in style) { var _nextValue = styleRule.style[_prop]; var _prevValue = style[_prop]; // We need to use `force: true` because `rule.style` has been updated during onUpdate hook, so `rule.prop()` will not update the CSSOM rule. // We do this comparison to avoid unneeded `rule.prop()` calls, since we have the old `style` object here. if (_nextValue == null && _nextValue !== _prevValue) { styleRule.prop(_prop, null, forceUpdateOptions); } } } } /** * Convert rules to a CSS string. */ ; _proto.toString = function toString(options) { var str = ''; var sheet = this.options.sheet; var link = sheet ? sheet.options.link : false; for (var index = 0; index < this.index.length; index++) { var rule = this.index[index]; var css = rule.toString(options); // No need to render an empty rule. if (!css && !link) continue; if (str) str += '\n'; str += css; } return str; }; return RuleList; }(); var StyleSheet = /*#__PURE__*/ function () { function StyleSheet(styles, options) { this.options = void 0; this.deployed = void 0; this.attached = void 0; this.rules = void 0; this.renderer = void 0; this.classes = void 0; this.keyframes = void 0; this.queue = void 0; this.attached = false; this.deployed = false; this.classes = {}; this.keyframes = {}; this.options = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { sheet: this, parent: this, classes: this.classes, keyframes: this.keyframes }); if (options.Renderer) { this.renderer = new options.Renderer(this); } this.rules = new RuleList(this.options); for (var name in styles) { this.rules.add(name, styles[name]); } this.rules.process(); } /** * Attach renderable to the render tree. */ var _proto = StyleSheet.prototype; _proto.attach = function attach() { if (this.attached) return this; if (this.renderer) this.renderer.attach(); this.attached = true; // Order is important, because we can't use insertRule API if style element is not attached. if (!this.deployed) this.deploy(); return this; } /** * Remove renderable from render tree. */ ; _proto.detach = function detach() { if (!this.attached) return this; if (this.renderer) this.renderer.detach(); this.attached = false; return this; } /** * Add a rule to the current stylesheet. * Will insert a rule also after the stylesheet has been rendered first time. */ ; _proto.addRule = function addRule(name, decl, options) { var queue = this.queue; // Plugins can create rules. // In order to preserve the right order, we need to queue all `.addRule` calls, // which happen after the first `rules.add()` call. if (this.attached && !queue) this.queue = []; var rule = this.rules.add(name, decl, options); if (!rule) return null; this.options.jss.plugins.onProcessRule(rule); if (this.attached) { if (!this.deployed) return rule; // Don't insert rule directly if there is no stringified version yet. // It will be inserted all together when .attach is called. if (queue) queue.push(rule);else { this.insertRule(rule); if (this.queue) { this.queue.forEach(this.insertRule, this); this.queue = undefined; } } return rule; } // We can't add rules to a detached style node. // We will redeploy the sheet once user will attach it. this.deployed = false; return rule; } /** * Insert rule into the StyleSheet */ ; _proto.insertRule = function insertRule(rule) { if (this.renderer) { this.renderer.insertRule(rule); } } /** * Create and add rules. * Will render also after Style Sheet was rendered the first time. */ ; _proto.addRules = function addRules(styles, options) { var added = []; for (var name in styles) { var rule = this.addRule(name, styles[name], options); if (rule) added.push(rule); } return added; } /** * Get a rule by name. */ ; _proto.getRule = function getRule(name) { return this.rules.get(name); } /** * Delete a rule by name. * Returns `true`: if rule has been deleted from the DOM. */ ; _proto.deleteRule = function deleteRule(name) { var rule = typeof name === 'object' ? name : this.rules.get(name); if (!rule || // Style sheet was created without link: true and attached, in this case we // won't be able to remove the CSS rule from the DOM. this.attached && !rule.renderable) { return false; } this.rules.remove(rule); if (this.attached && rule.renderable && this.renderer) { return this.renderer.deleteRule(rule.renderable); } return true; } /** * Get index of a rule. */ ; _proto.indexOf = function indexOf(rule) { return this.rules.indexOf(rule); } /** * Deploy pure CSS string to a renderable. */ ; _proto.deploy = function deploy() { if (this.renderer) this.renderer.deploy(); this.deployed = true; return this; } /** * Update the function values with a new data. */ ; _proto.update = function update() { var _this$rules; (_this$rules = this.rules).update.apply(_this$rules, arguments); return this; } /** * Updates a single rule. */ ; _proto.updateOne = function updateOne(rule, data, options) { this.rules.updateOne(rule, data, options); return this; } /** * Convert rules to a CSS string. */ ; _proto.toString = function toString(options) { return this.rules.toString(options); }; return StyleSheet; }(); var PluginsRegistry = /*#__PURE__*/ function () { function PluginsRegistry() { this.plugins = { internal: [], external: [] }; this.registry = void 0; } var _proto = PluginsRegistry.prototype; /** * Call `onCreateRule` hooks and return an object if returned by a hook. */ _proto.onCreateRule = function onCreateRule(name, decl, options) { for (var i = 0; i < this.registry.onCreateRule.length; i++) { var rule = this.registry.onCreateRule[i](name, decl, options); if (rule) return rule; } return null; } /** * Call `onProcessRule` hooks. */ ; _proto.onProcessRule = function onProcessRule(rule) { if (rule.isProcessed) return; var sheet = rule.options.sheet; for (var i = 0; i < this.registry.onProcessRule.length; i++) { this.registry.onProcessRule[i](rule, sheet); } if (rule.style) this.onProcessStyle(rule.style, rule, sheet); rule.isProcessed = true; } /** * Call `onProcessStyle` hooks. */ ; _proto.onProcessStyle = function onProcessStyle(style, rule, sheet) { for (var i = 0; i < this.registry.onProcessStyle.length; i++) { // $FlowFixMe[prop-missing] rule.style = this.registry.onProcessStyle[i](rule.style, rule, sheet); } } /** * Call `onProcessSheet` hooks. */ ; _proto.onProcessSheet = function onProcessSheet(sheet) { for (var i = 0; i < this.registry.onProcessSheet.length; i++) { this.registry.onProcessSheet[i](sheet); } } /** * Call `onUpdate` hooks. */ ; _proto.onUpdate = function onUpdate(data, rule, sheet, options) { for (var i = 0; i < this.registry.onUpdate.length; i++) { this.registry.onUpdate[i](data, rule, sheet, options); } } /** * Call `onChangeValue` hooks. */ ; _proto.onChangeValue = function onChangeValue(value, prop, rule) { var processedValue = value; for (var i = 0; i < this.registry.onChangeValue.length; i++) { processedValue = this.registry.onChangeValue[i](processedValue, prop, rule); } return processedValue; } /** * Register a plugin. */ ; _proto.use = function use(newPlugin, options) { if (options === void 0) { options = { queue: 'external' }; } var plugins = this.plugins[options.queue]; // Avoids applying same plugin twice, at least based on ref. if (plugins.indexOf(newPlugin) !== -1) { return; } plugins.push(newPlugin); this.registry = [].concat(this.plugins.external, this.plugins.internal).reduce(function (registry, plugin) { for (var name in plugin) { if (name in registry) { registry[name].push(plugin[name]); } else { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] Unknown hook \"" + name + "\".") : undefined; } } return registry; }, { onCreateRule: [], onProcessRule: [], onProcessStyle: [], onProcessSheet: [], onChangeValue: [], onUpdate: [] }); }; return PluginsRegistry; }(); /** * Sheets registry to access them all at one place. */ var SheetsRegistry = /*#__PURE__*/ function () { function SheetsRegistry() { this.registry = []; } var _proto = SheetsRegistry.prototype; /** * Register a Style Sheet. */ _proto.add = function add(sheet) { var registry = this.registry; var index = sheet.options.index; if (registry.indexOf(sheet) !== -1) return; if (registry.length === 0 || index >= this.index) { registry.push(sheet); return; } // Find a position. for (var i = 0; i < registry.length; i++) { if (registry[i].options.index > index) { registry.splice(i, 0, sheet); return; } } } /** * Reset the registry. */ ; _proto.reset = function reset() { this.registry = []; } /** * Remove a Style Sheet. */ ; _proto.remove = function remove(sheet) { var index = this.registry.indexOf(sheet); this.registry.splice(index, 1); } /** * Convert all attached sheets to a CSS string. */ ; _proto.toString = function toString(_temp) { var _ref = _temp === void 0 ? {} : _temp, attached = _ref.attached, options = Object(_babel_runtime_helpers_esm_objectWithoutPropertiesLoose__WEBPACK_IMPORTED_MODULE_6__["default"])(_ref, ["attached"]); var css = ''; for (var i = 0; i < this.registry.length; i++) { var sheet = this.registry[i]; if (attached != null && sheet.attached !== attached) { continue; } if (css) css += '\n'; css += sheet.toString(options); } return css; }; Object(_babel_runtime_helpers_esm_createClass__WEBPACK_IMPORTED_MODULE_3__["default"])(SheetsRegistry, [{ key: "index", /** * Current highest index number. */ get: function get() { return this.registry.length === 0 ? 0 : this.registry[this.registry.length - 1].options.index; } }]); return SheetsRegistry; }(); /** * This is a global sheets registry. Only DomRenderer will add sheets to it. * On the server one should use an own SheetsRegistry instance and add the * sheets to it, because you need to make sure to create a new registry for * each request in order to not leak sheets across requests. */ var registry = new SheetsRegistry(); /* eslint-disable */ // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var globalThis = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); var ns = '2f1acc6c3a606b082e5eef5e54414ffb'; if (globalThis[ns] == null) globalThis[ns] = 0; // Bundle may contain multiple JSS versions at the same time. In order to identify // the current version with just one short number and use it for classes generation // we use a counter. Also it is more accurate, because user can manually reevaluate // the module. var moduleId = globalThis[ns]++; var maxRules = 1e10; /** * Returns a function which generates unique class names based on counters. * When new generator function is created, rule counter is reseted. * We need to reset the rule counter for SSR for each request. */ var createGenerateId = function createGenerateId(options) { if (options === void 0) { options = {}; } var ruleCounter = 0; return function (rule, sheet) { ruleCounter += 1; if (ruleCounter > maxRules) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] You might have a memory leak. Rule counter is at " + ruleCounter + ".") : undefined; } var jssId = ''; var prefix = ''; if (sheet) { if (sheet.options.classNamePrefix) { prefix = sheet.options.classNamePrefix; } if (sheet.options.jss.id != null) { jssId = String(sheet.options.jss.id); } } if (options.minify) { // Using "c" because a number can't be the first char in a class name. return "" + (prefix || 'c') + moduleId + jssId + ruleCounter; } return prefix + rule.key + "-" + moduleId + (jssId ? "-" + jssId : '') + "-" + ruleCounter; }; }; /** * Cache the value from the first time a function is called. */ var memoize = function memoize(fn) { var value; return function () { if (!value) value = fn(); return value; }; }; /** * Get a style property value. */ var getPropertyValue = function getPropertyValue(cssRule, prop) { try { // Support CSSTOM. if (cssRule.attributeStyleMap) { return cssRule.attributeStyleMap.get(prop); } return cssRule.style.getPropertyValue(prop); } catch (err) { // IE may throw if property is unknown. return ''; } }; /** * Set a style property. */ var setProperty = function setProperty(cssRule, prop, value) { try { var cssValue = value; if (Array.isArray(value)) { cssValue = toCssValue(value, true); if (value[value.length - 1] === '!important') { cssRule.style.setProperty(prop, cssValue, 'important'); return true; } } // Support CSSTOM. if (cssRule.attributeStyleMap) { cssRule.attributeStyleMap.set(prop, cssValue); } else { cssRule.style.setProperty(prop, cssValue); } } catch (err) { // IE may throw if property is unknown. return false; } return true; }; /** * Remove a style property. */ var removeProperty = function removeProperty(cssRule, prop) { try { // Support CSSTOM. if (cssRule.attributeStyleMap) { cssRule.attributeStyleMap.delete(prop); } else { cssRule.style.removeProperty(prop); } } catch (err) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] DOMException \"" + err.message + "\" was thrown. Tried to remove property \"" + prop + "\".") : undefined; } }; /** * Set the selector. */ var setSelector = function setSelector(cssRule, selectorText) { cssRule.selectorText = selectorText; // Return false if setter was not successful. // Currently works in chrome only. return cssRule.selectorText === selectorText; }; /** * Gets the `head` element upon the first call and caches it. * We assume it can't be null. */ var getHead = memoize(function () { return document.querySelector('head'); }); /** * Find attached sheet with an index higher than the passed one. */ function findHigherSheet(registry, options) { for (var i = 0; i < registry.length; i++) { var sheet = registry[i]; if (sheet.attached && sheet.options.index > options.index && sheet.options.insertionPoint === options.insertionPoint) { return sheet; } } return null; } /** * Find attached sheet with the highest index. */ function findHighestSheet(registry, options) { for (var i = registry.length - 1; i >= 0; i--) { var sheet = registry[i]; if (sheet.attached && sheet.options.insertionPoint === options.insertionPoint) { return sheet; } } return null; } /** * Find a comment with "jss" inside. */ function findCommentNode(text) { var head = getHead(); for (var i = 0; i < head.childNodes.length; i++) { var node = head.childNodes[i]; if (node.nodeType === 8 && node.nodeValue.trim() === text) { return node; } } return null; } /** * Find a node before which we can insert the sheet. */ function findPrevNode(options) { var registry$1 = registry.registry; if (registry$1.length > 0) { // Try to insert before the next higher sheet. var sheet = findHigherSheet(registry$1, options); if (sheet && sheet.renderer) { return { parent: sheet.renderer.element.parentNode, node: sheet.renderer.element }; } // Otherwise insert after the last attached. sheet = findHighestSheet(registry$1, options); if (sheet && sheet.renderer) { return { parent: sheet.renderer.element.parentNode, node: sheet.renderer.element.nextSibling }; } } // Try to find a comment placeholder if registry is empty. var insertionPoint = options.insertionPoint; if (insertionPoint && typeof insertionPoint === 'string') { var comment = findCommentNode(insertionPoint); if (comment) { return { parent: comment.parentNode, node: comment.nextSibling }; } // If user specifies an insertion point and it can't be found in the document - // bad specificity issues may appear. true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] Insertion point \"" + insertionPoint + "\" not found.") : undefined; } return false; } /** * Insert style element into the DOM. */ function insertStyle(style, options) { var insertionPoint = options.insertionPoint; var nextNode = findPrevNode(options); if (nextNode !== false && nextNode.parent) { nextNode.parent.insertBefore(style, nextNode.node); return; } // Works with iframes and any node types. if (insertionPoint && typeof insertionPoint.nodeType === 'number') { // https://stackoverflow.com/questions/41328728/force-casting-in-flow var insertionPointElement = insertionPoint; var parentNode = insertionPointElement.parentNode; if (parentNode) parentNode.insertBefore(style, insertionPointElement.nextSibling);else true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, '[JSS] Insertion point is not in the DOM.') : undefined; return; } getHead().appendChild(style); } /** * Read jss nonce setting from the page if the user has set it. */ var getNonce = memoize(function () { var node = document.querySelector('meta[property="csp-nonce"]'); return node ? node.getAttribute('content') : null; }); var _insertRule = function insertRule(container, rule, index) { try { if ('insertRule' in container) { var c = container; c.insertRule(rule, index); } // Keyframes rule. else if ('appendRule' in container) { var _c = container; _c.appendRule(rule); } } catch (err) { true ? Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] " + err.message) : undefined; return false; } return container.cssRules[index]; }; var getValidRuleInsertionIndex = function getValidRuleInsertionIndex(container, index) { var maxIndex = container.cssRules.length; // In case previous insertion fails, passed index might be wrong if (index === undefined || index > maxIndex) { // eslint-disable-next-line no-param-reassign return maxIndex; } return index; }; var createStyle = function createStyle() { var el = document.createElement('style'); // Without it, IE will have a broken source order specificity if we // insert rules after we insert the style tag. // It seems to kick-off the source order specificity algorithm. el.textContent = '\n'; return el; }; var DomRenderer = /*#__PURE__*/ function () { // HTMLStyleElement needs fixing https://github.com/facebook/flow/issues/2696 // Will be empty if link: true option is not set, because // it is only for use together with insertRule API. function DomRenderer(sheet) { this.getPropertyValue = getPropertyValue; this.setProperty = setProperty; this.removeProperty = removeProperty; this.setSelector = setSelector; this.element = void 0; this.sheet = void 0; this.hasInsertedRules = false; this.cssRules = []; // There is no sheet when the renderer is used from a standalone StyleRule. if (sheet) registry.add(sheet); this.sheet = sheet; var _ref = this.sheet ? this.sheet.options : {}, media = _ref.media, meta = _ref.meta, element = _ref.element; this.element = element || createStyle(); this.element.setAttribute('data-jss', ''); if (media) this.element.setAttribute('media', media); if (meta) this.element.setAttribute('data-meta', meta); var nonce = getNonce(); if (nonce) this.element.setAttribute('nonce', nonce); } /** * Insert style element into render tree. */ var _proto = DomRenderer.prototype; _proto.attach = function attach() { // In the case the element node is external and it is already in the DOM. if (this.element.parentNode || !this.sheet) return; insertStyle(this.element, this.sheet.options); // When rules are inserted using `insertRule` API, after `sheet.detach().attach()` // most browsers create a new CSSStyleSheet, except of all IEs. var deployed = Boolean(this.sheet && this.sheet.deployed); if (this.hasInsertedRules && deployed) { this.hasInsertedRules = false; this.deploy(); } } /** * Remove style element from render tree. */ ; _proto.detach = function detach() { if (!this.sheet) return; var parentNode = this.element.parentNode; if (parentNode) parentNode.removeChild(this.element); // In the most browsers, rules inserted using insertRule() API will be lost when style element is removed. // Though IE will keep them and we need a consistent behavior. if (this.sheet.options.link) { this.cssRules = []; this.element.textContent = '\n'; } } /** * Inject CSS string into element. */ ; _proto.deploy = function deploy() { var sheet = this.sheet; if (!sheet) return; if (sheet.options.link) { this.insertRules(sheet.rules); return; } this.element.textContent = "\n" + sheet.toString() + "\n"; } /** * Insert RuleList into an element. */ ; _proto.insertRules = function insertRules(rules, nativeParent) { for (var i = 0; i < rules.index.length; i++) { this.insertRule(rules.index[i], i, nativeParent); } } /** * Insert a rule into element. */ ; _proto.insertRule = function insertRule(rule, index, nativeParent) { if (nativeParent === void 0) { nativeParent = this.element.sheet; } if (rule.rules) { var parent = rule; var latestNativeParent = nativeParent; if (rule.type === 'conditional' || rule.type === 'keyframes') { var _insertionIndex = getValidRuleInsertionIndex(nativeParent, index); // We need to render the container without children first. latestNativeParent = _insertRule(nativeParent, parent.toString({ children: false }), _insertionIndex); if (latestNativeParent === false) { return false; } this.refCssRule(rule, _insertionIndex, latestNativeParent); } this.insertRules(parent.rules, latestNativeParent); return latestNativeParent; } var ruleStr = rule.toString(); if (!ruleStr) return false; var insertionIndex = getValidRuleInsertionIndex(nativeParent, index); var nativeRule = _insertRule(nativeParent, ruleStr, insertionIndex); if (nativeRule === false) { return false; } this.hasInsertedRules = true; this.refCssRule(rule, insertionIndex, nativeRule); return nativeRule; }; _proto.refCssRule = function refCssRule(rule, index, cssRule) { rule.renderable = cssRule; // We only want to reference the top level rules, deleteRule API doesn't support removing nested rules // like rules inside media queries or keyframes if (rule.options.parent instanceof StyleSheet) { this.cssRules[index] = cssRule; } } /** * Delete a rule. */ ; _proto.deleteRule = function deleteRule(cssRule) { var sheet = this.element.sheet; var index = this.indexOf(cssRule); if (index === -1) return false; sheet.deleteRule(index); this.cssRules.splice(index, 1); return true; } /** * Get index of a CSS Rule. */ ; _proto.indexOf = function indexOf(cssRule) { return this.cssRules.indexOf(cssRule); } /** * Generate a new CSS rule and replace the existing one. * * Only used for some old browsers because they can't set a selector. */ ; _proto.replaceRule = function replaceRule(cssRule, rule) { var index = this.indexOf(cssRule); if (index === -1) return false; this.element.sheet.deleteRule(index); this.cssRules.splice(index, 1); return this.insertRule(rule, index); } /** * Get all rules elements. */ ; _proto.getRules = function getRules() { return this.element.sheet.cssRules; }; return DomRenderer; }(); var instanceCounter = 0; var Jss = /*#__PURE__*/ function () { function Jss(options) { this.id = instanceCounter++; this.version = "10.5.1"; this.plugins = new PluginsRegistry(); this.options = { id: { minify: false }, createGenerateId: createGenerateId, Renderer: is_in_browser__WEBPACK_IMPORTED_MODULE_1__["default"] ? DomRenderer : null, plugins: [] }; this.generateId = createGenerateId({ minify: false }); for (var i = 0; i < plugins.length; i++) { this.plugins.use(plugins[i], { queue: 'internal' }); } this.setup(options); } /** * Prepares various options, applies plugins. * Should not be used twice on the same instance, because there is no plugins * deduplication logic. */ var _proto = Jss.prototype; _proto.setup = function setup(options) { if (options === void 0) { options = {}; } if (options.createGenerateId) { this.options.createGenerateId = options.createGenerateId; } if (options.id) { this.options.id = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, this.options.id, options.id); } if (options.createGenerateId || options.id) { this.generateId = this.options.createGenerateId(this.options.id); } if (options.insertionPoint != null) this.options.insertionPoint = options.insertionPoint; if ('Renderer' in options) { this.options.Renderer = options.Renderer; } // eslint-disable-next-line prefer-spread if (options.plugins) this.use.apply(this, options.plugins); return this; } /** * Create a Style Sheet. */ ; _proto.createStyleSheet = function createStyleSheet(styles, options) { if (options === void 0) { options = {}; } var _options = options, index = _options.index; if (typeof index !== 'number') { index = registry.index === 0 ? 0 : registry.index + 1; } var sheet = new StyleSheet(styles, Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { jss: this, generateId: options.generateId || this.generateId, insertionPoint: this.options.insertionPoint, Renderer: this.options.Renderer, index: index })); this.plugins.onProcessSheet(sheet); return sheet; } /** * Detach the Style Sheet and remove it from the registry. */ ; _proto.removeStyleSheet = function removeStyleSheet(sheet) { sheet.detach(); registry.remove(sheet); return this; } /** * Create a rule without a Style Sheet. * [Deprecated] will be removed in the next major version. */ ; _proto.createRule = function createRule$1(name, style, options) { if (style === void 0) { style = {}; } if (options === void 0) { options = {}; } // Enable rule without name for inline styles. if (typeof name === 'object') { // $FlowFixMe[incompatible-call] return this.createRule(undefined, name, style); } // $FlowFixMe[incompatible-type] var ruleOptions = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__["default"])({}, options, { name: name, jss: this, Renderer: this.options.Renderer }); if (!ruleOptions.generateId) ruleOptions.generateId = this.generateId; if (!ruleOptions.classes) ruleOptions.classes = {}; if (!ruleOptions.keyframes) ruleOptions.keyframes = {}; var rule = createRule(name, style, ruleOptions); if (rule) this.plugins.onProcessRule(rule); return rule; } /** * Register plugin. Passed function will be invoked with a rule instance. */ ; _proto.use = function use() { var _this = this; for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { plugins[_key] = arguments[_key]; } plugins.forEach(function (plugin) { _this.plugins.use(plugin); }); return this; }; return Jss; }(); /** * Extracts a styles object with only props that contain function values. */ function getDynamicStyles(styles) { var to = null; for (var key in styles) { var value = styles[key]; var type = typeof value; if (type === 'function') { if (!to) to = {}; to[key] = value; } else if (type === 'object' && value !== null && !Array.isArray(value)) { var extracted = getDynamicStyles(value); if (extracted) { if (!to) to = {}; to[key] = extracted; } } } return to; } /** * SheetsManager is like a WeakMap which is designed to count StyleSheet * instances and attach/detach automatically. */ var SheetsManager = /*#__PURE__*/ function () { function SheetsManager() { this.length = 0; this.sheets = new WeakMap(); } var _proto = SheetsManager.prototype; _proto.get = function get(key) { var entry = this.sheets.get(key); return entry && entry.sheet; }; _proto.add = function add(key, sheet) { if (this.sheets.has(key)) return; this.length++; this.sheets.set(key, { sheet: sheet, refs: 0 }); }; _proto.manage = function manage(key) { var entry = this.sheets.get(key); if (entry) { if (entry.refs === 0) { entry.sheet.attach(); } entry.refs++; return entry.sheet; } Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "[JSS] SheetsManager: can't find sheet to manage"); return undefined; }; _proto.unmanage = function unmanage(key) { var entry = this.sheets.get(key); if (entry) { if (entry.refs > 0) { entry.refs--; if (entry.refs === 0) entry.sheet.detach(); } } else { Object(tiny_warning__WEBPACK_IMPORTED_MODULE_2__["default"])(false, "SheetsManager: can't find sheet to unmanage"); } }; Object(_babel_runtime_helpers_esm_createClass__WEBPACK_IMPORTED_MODULE_3__["default"])(SheetsManager, [{ key: "size", get: function get() { return this.length; } }]); return SheetsManager; }(); /** * A better abstraction over CSS. * * @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present * @website https://github.com/cssinjs/jss * @license MIT */ /** * Export a constant indicating if this browser has CSSTOM support. * https://developers.google.com/web/updates/2018/03/cssom */ var hasCSSTOMSupport = typeof CSS === 'object' && CSS != null && 'number' in CSS; /** * Creates a new instance of Jss. */ var create = function create(options) { return new Jss(options); }; /** * A global Jss instance. */ var jss = create(); /* harmony default export */ __webpack_exports__["default"] = (jss); /***/ }), /***/ "./node_modules/lit-html/directives/style-map.js": /*!*******************************************************!*\ !*** ./node_modules/lit-html/directives/style-map.js ***! \*******************************************************/ /*! exports provided: styleMap */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "styleMap", function() { return styleMap; }); /* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../lit-html.js */ "./node_modules/lit-html/lit-html.js"); /** * @license * Copyright (c) 2018 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * Stores the StyleInfo object applied to a given AttributePart. * Used to unset existing values when a new StyleInfo object is applied. */ const previousStylePropertyCache = new WeakMap(); /** * A directive that applies CSS properties to an element. * * `styleMap` can only be used in the `style` attribute and must be the only * expression in the attribute. It takes the property names in the `styleInfo` * object and adds the property values as CSS properties. Property names with * dashes (`-`) are assumed to be valid CSS property names and set on the * element's style object using `setProperty()`. Names without dashes are * assumed to be camelCased JavaScript property names and set on the element's * style object using property assignment, allowing the style object to * translate JavaScript-style names to CSS property names. * * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size': * '0'})` sets the `background-color`, `border-top` and `--size` properties. * * @param styleInfo {StyleInfo} */ const styleMap = Object(_lit_html_js__WEBPACK_IMPORTED_MODULE_0__["directive"])((styleInfo) => (part) => { if (!(part instanceof _lit_html_js__WEBPACK_IMPORTED_MODULE_0__["AttributePart"]) || (part instanceof _lit_html_js__WEBPACK_IMPORTED_MODULE_0__["PropertyPart"]) || part.committer.name !== 'style' || part.committer.parts.length > 1) { throw new Error('The `styleMap` directive must be used in the style attribute ' + 'and must be the only part in the attribute.'); } const { committer } = part; const { style } = committer.element; let previousStyleProperties = previousStylePropertyCache.get(part); if (previousStyleProperties === undefined) { // Write static styles once style.cssText = committer.strings.join(' '); previousStylePropertyCache.set(part, previousStyleProperties = new Set()); } // Remove old properties that no longer exist in styleInfo // We use forEach() instead of for-of so that re don't require down-level // iteration. previousStyleProperties.forEach((name) => { if (!(name in styleInfo)) { previousStyleProperties.delete(name); if (name.indexOf('-') === -1) { // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = null; } else { style.removeProperty(name); } } }); // Add or update properties for (const name in styleInfo) { previousStyleProperties.add(name); if (name.indexOf('-') === -1) { // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = styleInfo[name]; } else { style.setProperty(name, styleInfo[name]); } } }); //# sourceMappingURL=style-map.js.map /***/ }), /***/ "./node_modules/lit-html/lib/default-template-processor.js": /*!*****************************************************************!*\ !*** ./node_modules/lit-html/lib/default-template-processor.js ***! \*****************************************************************/ /*! exports provided: DefaultTemplateProcessor, defaultTemplateProcessor */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultTemplateProcessor", function() { return DefaultTemplateProcessor; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultTemplateProcessor", function() { return defaultTemplateProcessor; }); /* harmony import */ var _parts_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./parts.js */ "./node_modules/lit-html/lib/parts.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * Creates Parts when a template is instantiated. */ class DefaultTemplateProcessor { /** * Create parts for an attribute-position binding, given the event, attribute * name, and string literals. * * @param element The element containing the binding * @param name The attribute name * @param strings The string literals. There are always at least two strings, * event for fully-controlled bindings with a single expression. */ handleAttributeExpressions(element, name, strings, options) { const prefix = name[0]; if (prefix === '.') { const committer = new _parts_js__WEBPACK_IMPORTED_MODULE_0__["PropertyCommitter"](element, name.slice(1), strings); return committer.parts; } if (prefix === '@') { return [new _parts_js__WEBPACK_IMPORTED_MODULE_0__["EventPart"](element, name.slice(1), options.eventContext)]; } if (prefix === '?') { return [new _parts_js__WEBPACK_IMPORTED_MODULE_0__["BooleanAttributePart"](element, name.slice(1), strings)]; } const committer = new _parts_js__WEBPACK_IMPORTED_MODULE_0__["AttributeCommitter"](element, name, strings); return committer.parts; } /** * Create parts for a text-position binding. * @param templateFactory */ handleTextExpression(options) { return new _parts_js__WEBPACK_IMPORTED_MODULE_0__["NodePart"](options); } } const defaultTemplateProcessor = new DefaultTemplateProcessor(); //# sourceMappingURL=default-template-processor.js.map /***/ }), /***/ "./node_modules/lit-html/lib/directive.js": /*!************************************************!*\ !*** ./node_modules/lit-html/lib/directive.js ***! \************************************************/ /*! exports provided: directive, isDirective */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "directive", function() { return directive; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDirective", function() { return isDirective; }); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ const directives = new WeakMap(); /** * Brands a function as a directive factory function so that lit-html will call * the function during template rendering, rather than passing as a value. * * A _directive_ is a function that takes a Part as an argument. It has the * signature: `(part: Part) => void`. * * A directive _factory_ is a function that takes arguments for data and * configuration and returns a directive. Users of directive usually refer to * the directive factory as the directive. For example, "The repeat directive". * * Usually a template author will invoke a directive factory in their template * with relevant arguments, which will then return a directive function. * * Here's an example of using the `repeat()` directive factory that takes an * array and a function to render an item: * * ```js * html`
    <${repeat(items, (item) => html`
  • ${item}
  • `)}
` * ``` * * When `repeat` is invoked, it returns a directive function that closes over * `items` and the template function. When the outer template is rendered, the * return directive function is called with the Part for the expression. * `repeat` then performs it's custom logic to render multiple items. * * @param f The directive factory function. Must be a function that returns a * function of the signature `(part: Part) => void`. The returned function will * be called with the part object. * * @example * * import {directive, html} from 'lit-html'; * * const immutable = directive((v) => (part) => { * if (part.value !== v) { * part.setValue(v) * } * }); */ const directive = (f) => ((...args) => { const d = f(...args); directives.set(d, true); return d; }); const isDirective = (o) => { return typeof o === 'function' && directives.has(o); }; //# sourceMappingURL=directive.js.map /***/ }), /***/ "./node_modules/lit-html/lib/dom.js": /*!******************************************!*\ !*** ./node_modules/lit-html/lib/dom.js ***! \******************************************/ /*! exports provided: isCEPolyfill, reparentNodes, removeNodes */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isCEPolyfill", function() { return isCEPolyfill; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reparentNodes", function() { return reparentNodes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeNodes", function() { return removeNodes; }); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * True if the custom elements polyfill is in use. */ const isCEPolyfill = typeof window !== 'undefined' && window.customElements != null && window.customElements.polyfillWrapFlushCallback !== undefined; /** * Reparents nodes, starting from `start` (inclusive) to `end` (exclusive), * into another container (could be the same container), before `before`. If * `before` is null, it appends the nodes to the container. */ const reparentNodes = (container, start, end = null, before = null) => { while (start !== end) { const n = start.nextSibling; container.insertBefore(start, before); start = n; } }; /** * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from * `container`. */ const removeNodes = (container, start, end = null) => { while (start !== end) { const n = start.nextSibling; container.removeChild(start); start = n; } }; //# sourceMappingURL=dom.js.map /***/ }), /***/ "./node_modules/lit-html/lib/part.js": /*!*******************************************!*\ !*** ./node_modules/lit-html/lib/part.js ***! \*******************************************/ /*! exports provided: noChange, nothing */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "noChange", function() { return noChange; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "nothing", function() { return nothing; }); /** * @license * Copyright (c) 2018 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * A sentinel value that signals that a value was handled by a directive and * should not be written to the DOM. */ const noChange = {}; /** * A sentinel value that signals a NodePart to fully clear its content. */ const nothing = {}; //# sourceMappingURL=part.js.map /***/ }), /***/ "./node_modules/lit-html/lib/parts.js": /*!********************************************!*\ !*** ./node_modules/lit-html/lib/parts.js ***! \********************************************/ /*! exports provided: isPrimitive, isIterable, AttributeCommitter, AttributePart, NodePart, BooleanAttributePart, PropertyCommitter, PropertyPart, EventPart */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPrimitive", function() { return isPrimitive; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isIterable", function() { return isIterable; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttributeCommitter", function() { return AttributeCommitter; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttributePart", function() { return AttributePart; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodePart", function() { return NodePart; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BooleanAttributePart", function() { return BooleanAttributePart; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PropertyCommitter", function() { return PropertyCommitter; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PropertyPart", function() { return PropertyPart; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EventPart", function() { return EventPart; }); /* harmony import */ var _directive_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./directive.js */ "./node_modules/lit-html/lib/directive.js"); /* harmony import */ var _dom_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dom.js */ "./node_modules/lit-html/lib/dom.js"); /* harmony import */ var _part_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./part.js */ "./node_modules/lit-html/lib/part.js"); /* harmony import */ var _template_instance_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./template-instance.js */ "./node_modules/lit-html/lib/template-instance.js"); /* harmony import */ var _template_result_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./template-result.js */ "./node_modules/lit-html/lib/template-result.js"); /* harmony import */ var _template_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./template.js */ "./node_modules/lit-html/lib/template.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ const isPrimitive = (value) => { return (value === null || !(typeof value === 'object' || typeof value === 'function')); }; const isIterable = (value) => { return Array.isArray(value) || // eslint-disable-next-line @typescript-eslint/no-explicit-any !!(value && value[Symbol.iterator]); }; /** * Writes attribute values to the DOM for a group of AttributeParts bound to a * single attribute. The value is only set once even if there are multiple parts * for an attribute. */ class AttributeCommitter { constructor(element, name, strings) { this.dirty = true; this.element = element; this.name = name; this.strings = strings; this.parts = []; for (let i = 0; i < strings.length - 1; i++) { this.parts[i] = this._createPart(); } } /** * Creates a single part. Override this to create a differnt type of part. */ _createPart() { return new AttributePart(this); } _getValue() { const strings = this.strings; const l = strings.length - 1; const parts = this.parts; // If we're assigning an attribute via syntax like: // attr="${foo}" or attr=${foo} // but not // attr="${foo} ${bar}" or attr="${foo} baz" // then we don't want to coerce the attribute value into one long // string. Instead we want to just return the value itself directly, // so that sanitizeDOMValue can get the actual value rather than // String(value) // The exception is if v is an array, in which case we do want to smash // it together into a string without calling String() on the array. // // This also allows trusted values (when using TrustedTypes) being // assigned to DOM sinks without being stringified in the process. if (l === 1 && strings[0] === '' && strings[1] === '') { const v = parts[0].value; if (typeof v === 'symbol') { return String(v); } if (typeof v === 'string' || !isIterable(v)) { return v; } } let text = ''; for (let i = 0; i < l; i++) { text += strings[i]; const part = parts[i]; if (part !== undefined) { const v = part.value; if (isPrimitive(v) || !isIterable(v)) { text += typeof v === 'string' ? v : String(v); } else { for (const t of v) { text += typeof t === 'string' ? t : String(t); } } } } text += strings[l]; return text; } commit() { if (this.dirty) { this.dirty = false; this.element.setAttribute(this.name, this._getValue()); } } } /** * A Part that controls all or part of an attribute value. */ class AttributePart { constructor(committer) { this.value = undefined; this.committer = committer; } setValue(value) { if (value !== _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"] && (!isPrimitive(value) || value !== this.value)) { this.value = value; // If the value is a not a directive, dirty the committer so that it'll // call setAttribute. If the value is a directive, it'll dirty the // committer if it calls setValue(). if (!Object(_directive_js__WEBPACK_IMPORTED_MODULE_0__["isDirective"])(value)) { this.committer.dirty = true; } } } commit() { while (Object(_directive_js__WEBPACK_IMPORTED_MODULE_0__["isDirective"])(this.value)) { const directive = this.value; this.value = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; directive(this); } if (this.value === _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]) { return; } this.committer.commit(); } } /** * A Part that controls a location within a Node tree. Like a Range, NodePart * has start and end locations and can set and update the Nodes between those * locations. * * NodeParts support several value types: primitives, Nodes, TemplateResults, * as well as arrays and iterables of those types. */ class NodePart { constructor(options) { this.value = undefined; this.__pendingValue = undefined; this.options = options; } /** * Appends this part into a container. * * This part must be empty, as its contents are not automatically moved. */ appendInto(container) { this.startNode = container.appendChild(Object(_template_js__WEBPACK_IMPORTED_MODULE_5__["createMarker"])()); this.endNode = container.appendChild(Object(_template_js__WEBPACK_IMPORTED_MODULE_5__["createMarker"])()); } /** * Inserts this part after the `ref` node (between `ref` and `ref`'s next * sibling). Both `ref` and its next sibling must be static, unchanging nodes * such as those that appear in a literal section of a template. * * This part must be empty, as its contents are not automatically moved. */ insertAfterNode(ref) { this.startNode = ref; this.endNode = ref.nextSibling; } /** * Appends this part into a parent part. * * This part must be empty, as its contents are not automatically moved. */ appendIntoPart(part) { part.__insert(this.startNode = Object(_template_js__WEBPACK_IMPORTED_MODULE_5__["createMarker"])()); part.__insert(this.endNode = Object(_template_js__WEBPACK_IMPORTED_MODULE_5__["createMarker"])()); } /** * Inserts this part after the `ref` part. * * This part must be empty, as its contents are not automatically moved. */ insertAfterPart(ref) { ref.__insert(this.startNode = Object(_template_js__WEBPACK_IMPORTED_MODULE_5__["createMarker"])()); this.endNode = ref.endNode; ref.endNode = this.startNode; } setValue(value) { this.__pendingValue = value; } commit() { if (this.startNode.parentNode === null) { return; } while (Object(_directive_js__WEBPACK_IMPORTED_MODULE_0__["isDirective"])(this.__pendingValue)) { const directive = this.__pendingValue; this.__pendingValue = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; directive(this); } const value = this.__pendingValue; if (value === _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]) { return; } if (isPrimitive(value)) { if (value !== this.value) { this.__commitText(value); } } else if (value instanceof _template_result_js__WEBPACK_IMPORTED_MODULE_4__["TemplateResult"]) { this.__commitTemplateResult(value); } else if (value instanceof Node) { this.__commitNode(value); } else if (isIterable(value)) { this.__commitIterable(value); } else if (value === _part_js__WEBPACK_IMPORTED_MODULE_2__["nothing"]) { this.value = _part_js__WEBPACK_IMPORTED_MODULE_2__["nothing"]; this.clear(); } else { // Fallback, will render the string representation this.__commitText(value); } } __insert(node) { this.endNode.parentNode.insertBefore(node, this.endNode); } __commitNode(value) { if (this.value === value) { return; } this.clear(); this.__insert(value); this.value = value; } __commitText(value) { const node = this.startNode.nextSibling; value = value == null ? '' : value; // If `value` isn't already a string, we explicitly convert it here in case // it can't be implicitly converted - i.e. it's a symbol. const valueAsString = typeof value === 'string' ? value : String(value); if (node === this.endNode.previousSibling && node.nodeType === 3 /* Node.TEXT_NODE */) { // If we only have a single text node between the markers, we can just // set its value, rather than replacing it. // TODO(justinfagnani): Can we just check if this.value is primitive? node.data = valueAsString; } else { this.__commitNode(document.createTextNode(valueAsString)); } this.value = value; } __commitTemplateResult(value) { const template = this.options.templateFactory(value); if (this.value instanceof _template_instance_js__WEBPACK_IMPORTED_MODULE_3__["TemplateInstance"] && this.value.template === template) { this.value.update(value.values); } else { // Make sure we propagate the template processor from the TemplateResult // so that we use its syntax extension, etc. The template factory comes // from the render function options so that it can control template // caching and preprocessing. const instance = new _template_instance_js__WEBPACK_IMPORTED_MODULE_3__["TemplateInstance"](template, value.processor, this.options); const fragment = instance._clone(); instance.update(value.values); this.__commitNode(fragment); this.value = instance; } } __commitIterable(value) { // For an Iterable, we create a new InstancePart per item, then set its // value to the item. This is a little bit of overhead for every item in // an Iterable, but it lets us recurse easily and efficiently update Arrays // of TemplateResults that will be commonly returned from expressions like: // array.map((i) => html`${i}`), by reusing existing TemplateInstances. // If _value is an array, then the previous render was of an // iterable and _value will contain the NodeParts from the previous // render. If _value is not an array, clear this part and make a new // array for NodeParts. if (!Array.isArray(this.value)) { this.value = []; this.clear(); } // Lets us keep track of how many items we stamped so we can clear leftover // items from a previous render const itemParts = this.value; let partIndex = 0; let itemPart; for (const item of value) { // Try to reuse an existing part itemPart = itemParts[partIndex]; // If no existing part, create a new one if (itemPart === undefined) { itemPart = new NodePart(this.options); itemParts.push(itemPart); if (partIndex === 0) { itemPart.appendIntoPart(this); } else { itemPart.insertAfterPart(itemParts[partIndex - 1]); } } itemPart.setValue(item); itemPart.commit(); partIndex++; } if (partIndex < itemParts.length) { // Truncate the parts array so _value reflects the current state itemParts.length = partIndex; this.clear(itemPart && itemPart.endNode); } } clear(startNode = this.startNode) { Object(_dom_js__WEBPACK_IMPORTED_MODULE_1__["removeNodes"])(this.startNode.parentNode, startNode.nextSibling, this.endNode); } } /** * Implements a boolean attribute, roughly as defined in the HTML * specification. * * If the value is truthy, then the attribute is present with a value of * ''. If the value is falsey, the attribute is removed. */ class BooleanAttributePart { constructor(element, name, strings) { this.value = undefined; this.__pendingValue = undefined; if (strings.length !== 2 || strings[0] !== '' || strings[1] !== '') { throw new Error('Boolean attributes can only contain a single expression'); } this.element = element; this.name = name; this.strings = strings; } setValue(value) { this.__pendingValue = value; } commit() { while (Object(_directive_js__WEBPACK_IMPORTED_MODULE_0__["isDirective"])(this.__pendingValue)) { const directive = this.__pendingValue; this.__pendingValue = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; directive(this); } if (this.__pendingValue === _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]) { return; } const value = !!this.__pendingValue; if (this.value !== value) { if (value) { this.element.setAttribute(this.name, ''); } else { this.element.removeAttribute(this.name); } this.value = value; } this.__pendingValue = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; } } /** * Sets attribute values for PropertyParts, so that the value is only set once * even if there are multiple parts for a property. * * If an expression controls the whole property value, then the value is simply * assigned to the property under control. If there are string literals or * multiple expressions, then the strings are expressions are interpolated into * a string first. */ class PropertyCommitter extends AttributeCommitter { constructor(element, name, strings) { super(element, name, strings); this.single = (strings.length === 2 && strings[0] === '' && strings[1] === ''); } _createPart() { return new PropertyPart(this); } _getValue() { if (this.single) { return this.parts[0].value; } return super._getValue(); } commit() { if (this.dirty) { this.dirty = false; // eslint-disable-next-line @typescript-eslint/no-explicit-any this.element[this.name] = this._getValue(); } } } class PropertyPart extends AttributePart { } // Detect event listener options support. If the `capture` property is read // from the options object, then options are supported. If not, then the third // argument to add/removeEventListener is interpreted as the boolean capture // value so we should only pass the `capture` property. let eventOptionsSupported = false; // Wrap into an IIFE because MS Edge <= v41 does not support having try/catch // blocks right into the body of a module (() => { try { const options = { get capture() { eventOptionsSupported = true; return false; } }; // eslint-disable-next-line @typescript-eslint/no-explicit-any window.addEventListener('test', options, options); // eslint-disable-next-line @typescript-eslint/no-explicit-any window.removeEventListener('test', options, options); } catch (_e) { // event options not supported } })(); class EventPart { constructor(element, eventName, eventContext) { this.value = undefined; this.__pendingValue = undefined; this.element = element; this.eventName = eventName; this.eventContext = eventContext; this.__boundHandleEvent = (e) => this.handleEvent(e); } setValue(value) { this.__pendingValue = value; } commit() { while (Object(_directive_js__WEBPACK_IMPORTED_MODULE_0__["isDirective"])(this.__pendingValue)) { const directive = this.__pendingValue; this.__pendingValue = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; directive(this); } if (this.__pendingValue === _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]) { return; } const newListener = this.__pendingValue; const oldListener = this.value; const shouldRemoveListener = newListener == null || oldListener != null && (newListener.capture !== oldListener.capture || newListener.once !== oldListener.once || newListener.passive !== oldListener.passive); const shouldAddListener = newListener != null && (oldListener == null || shouldRemoveListener); if (shouldRemoveListener) { this.element.removeEventListener(this.eventName, this.__boundHandleEvent, this.__options); } if (shouldAddListener) { this.__options = getOptions(newListener); this.element.addEventListener(this.eventName, this.__boundHandleEvent, this.__options); } this.value = newListener; this.__pendingValue = _part_js__WEBPACK_IMPORTED_MODULE_2__["noChange"]; } handleEvent(event) { if (typeof this.value === 'function') { this.value.call(this.eventContext || this.element, event); } else { this.value.handleEvent(event); } } } // We copy options because of the inconsistent behavior of browsers when reading // the third argument of add/removeEventListener. IE11 doesn't support options // at all. Chrome 41 only reads `capture` if the argument is an object. const getOptions = (o) => o && (eventOptionsSupported ? { capture: o.capture, passive: o.passive, once: o.once } : o.capture); //# sourceMappingURL=parts.js.map /***/ }), /***/ "./node_modules/lit-html/lib/render.js": /*!*********************************************!*\ !*** ./node_modules/lit-html/lib/render.js ***! \*********************************************/ /*! exports provided: parts, render */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parts", function() { return parts; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; }); /* harmony import */ var _dom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dom.js */ "./node_modules/lit-html/lib/dom.js"); /* harmony import */ var _parts_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./parts.js */ "./node_modules/lit-html/lib/parts.js"); /* harmony import */ var _template_factory_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./template-factory.js */ "./node_modules/lit-html/lib/template-factory.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ const parts = new WeakMap(); /** * Renders a template result or other value to a container. * * To update a container with new values, reevaluate the template literal and * call `render` with the new result. * * @param result Any value renderable by NodePart - typically a TemplateResult * created by evaluating a template tag like `html` or `svg`. * @param container A DOM parent to render to. The entire contents are either * replaced, or efficiently updated if the same result type was previous * rendered there. * @param options RenderOptions for the entire render tree rendered to this * container. Render options must *not* change between renders to the same * container, as those changes will not effect previously rendered DOM. */ const render = (result, container, options) => { let part = parts.get(container); if (part === undefined) { Object(_dom_js__WEBPACK_IMPORTED_MODULE_0__["removeNodes"])(container, container.firstChild); parts.set(container, part = new _parts_js__WEBPACK_IMPORTED_MODULE_1__["NodePart"](Object.assign({ templateFactory: _template_factory_js__WEBPACK_IMPORTED_MODULE_2__["templateFactory"] }, options))); part.appendInto(container); } part.setValue(result); part.commit(); }; //# sourceMappingURL=render.js.map /***/ }), /***/ "./node_modules/lit-html/lib/template-factory.js": /*!*******************************************************!*\ !*** ./node_modules/lit-html/lib/template-factory.js ***! \*******************************************************/ /*! exports provided: templateFactory, templateCaches */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "templateFactory", function() { return templateFactory; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "templateCaches", function() { return templateCaches; }); /* harmony import */ var _template_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./template.js */ "./node_modules/lit-html/lib/template.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * The default TemplateFactory which caches Templates keyed on * result.type and result.strings. */ function templateFactory(result) { let templateCache = templateCaches.get(result.type); if (templateCache === undefined) { templateCache = { stringsArray: new WeakMap(), keyString: new Map() }; templateCaches.set(result.type, templateCache); } let template = templateCache.stringsArray.get(result.strings); if (template !== undefined) { return template; } // If the TemplateStringsArray is new, generate a key from the strings // This key is shared between all templates with identical content const key = result.strings.join(_template_js__WEBPACK_IMPORTED_MODULE_0__["marker"]); // Check if we already have a Template for this key template = templateCache.keyString.get(key); if (template === undefined) { // If we have not seen this key before, create a new Template template = new _template_js__WEBPACK_IMPORTED_MODULE_0__["Template"](result, result.getTemplateElement()); // Cache the Template for this key templateCache.keyString.set(key, template); } // Cache all future queries for this TemplateStringsArray templateCache.stringsArray.set(result.strings, template); return template; } const templateCaches = new Map(); //# sourceMappingURL=template-factory.js.map /***/ }), /***/ "./node_modules/lit-html/lib/template-instance.js": /*!********************************************************!*\ !*** ./node_modules/lit-html/lib/template-instance.js ***! \********************************************************/ /*! exports provided: TemplateInstance */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplateInstance", function() { return TemplateInstance; }); /* harmony import */ var _dom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dom.js */ "./node_modules/lit-html/lib/dom.js"); /* harmony import */ var _template_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./template.js */ "./node_modules/lit-html/lib/template.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * An instance of a `Template` that can be attached to the DOM and updated * with new values. */ class TemplateInstance { constructor(template, processor, options) { this.__parts = []; this.template = template; this.processor = processor; this.options = options; } update(values) { let i = 0; for (const part of this.__parts) { if (part !== undefined) { part.setValue(values[i]); } i++; } for (const part of this.__parts) { if (part !== undefined) { part.commit(); } } } _clone() { // There are a number of steps in the lifecycle of a template instance's // DOM fragment: // 1. Clone - create the instance fragment // 2. Adopt - adopt into the main document // 3. Process - find part markers and create parts // 4. Upgrade - upgrade custom elements // 5. Update - set node, attribute, property, etc., values // 6. Connect - connect to the document. Optional and outside of this // method. // // We have a few constraints on the ordering of these steps: // * We need to upgrade before updating, so that property values will pass // through any property setters. // * We would like to process before upgrading so that we're sure that the // cloned fragment is inert and not disturbed by self-modifying DOM. // * We want custom elements to upgrade even in disconnected fragments. // // Given these constraints, with full custom elements support we would // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect // // But Safari does not implement CustomElementRegistry#upgrade, so we // can not implement that order and still have upgrade-before-update and // upgrade disconnected fragments. So we instead sacrifice the // process-before-upgrade constraint, since in Custom Elements v1 elements // must not modify their light DOM in the constructor. We still have issues // when co-existing with CEv0 elements like Polymer 1, and with polyfills // that don't strictly adhere to the no-modification rule because shadow // DOM, which may be created in the constructor, is emulated by being placed // in the light DOM. // // The resulting order is on native is: Clone, Adopt, Upgrade, Process, // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade // in one step. // // The Custom Elements v1 polyfill supports upgrade(), so the order when // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update, // Connect. const fragment = _dom_js__WEBPACK_IMPORTED_MODULE_0__["isCEPolyfill"] ? this.template.element.content.cloneNode(true) : document.importNode(this.template.element.content, true); const stack = []; const parts = this.template.parts; // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false); let partIndex = 0; let nodeIndex = 0; let part; let node = walker.nextNode(); // Loop through all the nodes and parts of a template while (partIndex < parts.length) { part = parts[partIndex]; if (!Object(_template_js__WEBPACK_IMPORTED_MODULE_1__["isTemplatePartActive"])(part)) { this.__parts.push(undefined); partIndex++; continue; } // Progress the tree walker until we find our next part's node. // Note that multiple parts may share the same node (attribute parts // on a single element), so this loop may not run at all. while (nodeIndex < part.index) { nodeIndex++; if (node.nodeName === 'TEMPLATE') { stack.push(node); walker.currentNode = node.content; } if ((node = walker.nextNode()) === null) { // We've exhausted the content inside a nested template element. // Because we still have parts (the outer for-loop), we know: // - There is a template in the stack // - The walker will find a nextNode outside the template walker.currentNode = stack.pop(); node = walker.nextNode(); } } // We've arrived at our part's node. if (part.type === 'node') { const part = this.processor.handleTextExpression(this.options); part.insertAfterNode(node.previousSibling); this.__parts.push(part); } else { this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options)); } partIndex++; } if (_dom_js__WEBPACK_IMPORTED_MODULE_0__["isCEPolyfill"]) { document.adoptNode(fragment); customElements.upgrade(fragment); } return fragment; } } //# sourceMappingURL=template-instance.js.map /***/ }), /***/ "./node_modules/lit-html/lib/template-result.js": /*!******************************************************!*\ !*** ./node_modules/lit-html/lib/template-result.js ***! \******************************************************/ /*! exports provided: TemplateResult, SVGTemplateResult */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplateResult", function() { return TemplateResult; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SVGTemplateResult", function() { return SVGTemplateResult; }); /* harmony import */ var _dom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dom.js */ "./node_modules/lit-html/lib/dom.js"); /* harmony import */ var _template_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./template.js */ "./node_modules/lit-html/lib/template.js"); /** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ /** * @module lit-html */ /** * Our TrustedTypePolicy for HTML which is declared using the html template * tag function. * * That HTML is a developer-authored constant, and is parsed with innerHTML * before any untrusted expressions have been mixed in. Therefor it is * considered safe by construction. */ const policy = window.trustedTypes && trustedTypes.createPolicy('lit-html', { createHTML: (s) => s }); const commentMarker = ` ${_template_js__WEBPACK_IMPORTED_MODULE_1__["marker"]} `; /** * The return type of `html`, which holds a Template and the values from * interpolated expressions. */ class TemplateResult { constructor(strings, values, type, processor) { this.strings = strings; this.values = values; this.type = type; this.processor = processor; } /** * Returns a string of HTML used to create a `